RON THRONES & PATRIOTS
SINGLE-PLAYER SCENARIO SCRIPTING
BY MEAT PUPPET
VERSION 1, MAY 27, 2005
This document is intended to teach would-be RON TaP scenario designers the basic principles of scripting so they can create their own cool scenarios. Barring any typos or screw-ups, it should give you some good info on how to make basic RON scenario scripts.
The basic teaching tool is to look at an excerpt from an actual script, “Stalingrad”, and then lean the basics of scripting by dissecting it line by line. You’ll learn what each line of code means, and how they all tie together logically to make a script.
RON script looks like Chinese but once you get the hang of how the logic works, it’s all a matter of learning new script commands, and then you can create some really cool scenarios. The sky’s the limit.
So take a look here and learn the basics of how it all works, then start learning new commands available in the Script Editor (click EDIT, then INSERT TRIGGER FUNCTION) and also in the Word document “Script Functions Listing_2.doc” that came with your RON CD or is available in the forums at RON Heaven.
You can also learn by downloading other designer’s scenarios. Good artists borrow; great artists steal. Download their scenarios, open them in your Scenario Editor, click EDIT SCRIPT, and see how they did certain effects. Then copy and paste and adapt various sections of code to your own scenario. For example, if you like how somebody did a command-and-control toolbar, and you know the basics of scripting but don’t know what commands they used, open up their script and you’ll find out quickly how they did it.
Next, search the Internet for cool custom sound .wav files, make sure your map has lots of eye candy and as much realism as possible, and then your off to creating a great new scenario for everybody to enjoy.
Good luck!
- Meat Puppet, RON Scenario Designer
BASICS
Here’s basically what RON has to say about scripting if you look at their sample script. Use this as reference. After this section, we will look at a sample script (an excerpt from “Stalingrad”) and go step by step through the logic of a typical script.
//You can use the Script Editor to edit & debug scripts
//The editor is accessible:
// 1. from the Tools & Extras menu
// 2. through the Edit Script button in the Scenario Editor
// 3. Via the Ctrl + Alt + Z hotkey during game, which may be used to debug scripts
//Script debugging capabilities are enabled when the game is running.
//All scripts are are normally stored in .bhs files, which can be loaded and debugged in the Script Editor.
//Editing
//Scripts can be edited, saved and compiled through the Script Editor.
//It is generally recommended to edit the script from the main menu or from Scenario Editor "Edit Script" option.
//Trigger Function Library //Scenario Scripts The most fundamental part of a script is given to you by the Script Editor. It shows: scenario { } See those brackets? Those brackets designate the basic building blocks of the scenario. They basically say, “Whatever is in these brackets is an integral set of commands.” Next the script is expanded to include labels. I personally never use labels, but some script writers may find them useful to keep track of all the variables used in the script. scenario { labels { } } Next you’ll see the run_once section. This section is very important. It basically helps you set up your game. scenario { run_once { } } Sample things you can do in the run_once section include: •In-game written instructions Why is the run_once section important? Because it only runs once. The rest of your script will continually loop. RON will read the script from top to bottom, and execute each command one after the other in the order these commands are written in the script. When it reaches the last command in the script, it will then go back to the top and start again. The run_once section is the exception—RON will start at the top, execute all the commands listed, then when it reaches the last command it won’t loop but instead ignore that section for the rest of the scenario. Below is a sample run_once script from Stalingrad, just highlights, with commentary: scenario run_once { NOTE: I didn’t want player 2 (the human player) to suffer attrition while in enemy territory (the area around the Red Fort). How do we know who player 2 is? In the Scenario Editor, look at the players you have created in the upper left part of the screen. Player 1 is the first on the list, Player 2 is the second, etc. NOTE: See how there is a “;” at the end of the command. Every time you write a line of code, you will need a “;” at the end. NOTE (IMPORTANT!): Every time you type in a complete section of code, click COMPILE. The script you are working on will automatically save and debug itself. If you have a script error, the script editor will tell you, and then roughly show you where the error is (although it’s not always perfect in telling you where the error is). NOTE: See how this line of code is indented with two spaces from the run_once { above it. This basically says, “This line of code is part of the run_once section.” At the end of the section, you’ll see the closing bracket (}), and the indenting stops. In this way, the script kind of looks like an outline. NOTE: I made the Russian Shock Infantry unit 70% of its normal size. First I had to “find” these units and label them as a variable. The first line of code basically reads: Variable = Find Player 1 Shock Infantry. The second line reads: Set the size of Player 1’s Shock Infantry to 70% of its normal size. NOTE: This allowed me to take all Shock Infantry in the game and reset these units’ speed to 15. This way, for the first part of the scenario, I could have the Russian Shock Infantry “charge” the German positions at a faster than marching speed. Because all other units have a speed of 12, giving the Russians a speed of 15 makes it look like they’re running, charging the Germans. NOTE: These commands allow us to take existing RON civilizations such as Germans or Russians, and rename them to whatever we want to call them. NOTE; The “rename_type” command allowed us to rename standard RON buildings and unit types to whatever names we want to fit our scenario. A typical Russian WWII tank was the T34, so I renamed the game’s T80 Tank to become a T34 Tank. NOTE: I wanted to have the game’s “camera” zoom in on a particular part of the map designated by these x, y coordinates (68, 139). You can get the x, y coordinates in the Scenario Editor. Simply run your mouse over the map; you’ll see the x, y coordinates on the left for wherever you are. Knowing x, y coordinates are important because you’ll be using them a lot to tell the game where to build and move things. jump_camera(68,139); NOTE: To be sure the game centered on that part of the map, I told it to jump_camera. If you don’t want to zoom, this is a good way to start the game on a particular part of the map. All you need are the x,y coordinates you can get from your map in the Scenario Editor. play_sound("Waffen.wav"); NOTE: This plays a song. popup_dialog("1942. Germany's invasion of Russia. After initial successes, Hitler decides to launch an offensive along the southern front in an effort to seize strategic oil fields. The key to this region is a city on the Volga River, a city that bears the name of Hitler's sworn enemy-- STALINGRAD."); NOTE: popup_dialog is one of the most simple and important commands you’ll learn since it allows you to create in-game instructions and otherwise say things to the player during the game. The popup_dialog command is also good because it requires the player to press RETURN to get rid of it. The popup_dialog basically interrupts the game. set_timer("russian_attack1",20); NOTE: Here’s another very important script instruction: set_timer. This command creates a timer (“russian_attack1”) and then sets it to last 20 seconds. Later on, we will put in our script an instruction that basically says, “If the timer russian_attack1’s time is up, then do this and do this.” Note that when you make a variable like “russian_attack1”, every time you use that variable you should keep the exact same case. If you write “Russian_Attack1” later on, for example, the script editor won’t recognize it as the same variable. russian_attack1 and Russian_Attack1 are two different variables to RON. NOTE: I told RON to print game objectives on the lefthand side of the screen. The code shows three sections: (“Words the player sees on his screen”, “name_of_objective”, “sound_that_plays_when_objective_appears.wav”). In this scenario, we have fooled RON by creating a command toolbar that allows us to use a key to call in an artillery strike in the game, pretending it’s an objective. NOTE: Later on, we can remove the first objective by using this line of code: remove_objective("objective1a"); NOTE: Which means that the objective we created called objective1a is wiped off the screen and assumed to be completed. NOTE: The run_once section is now completed because we have written our closing bracket. Now the setup is over. Remember, the main script section loops—meaning, each line of script is read and executed by RON until it reaches the end, then it goes back to the top and starts over in a never-ending loop until the game is over. Let’s look at some code from Stalingrad and see what kinds of things we can do. Basically, we’ll go through the first mission of Stalingrad and a few other highlights. if (timer_expired("russian_attack1")) { NOTE: Remember in the run_once section we set a timer called russian_attack1 which would run for 20 seconds. This line of code basically says, “If the timer called russian_attack1 is over, then execute all commands after the bracket { and before the ending bracket }. Everything in between is indented so that you know that all of it is subordinate or part of the “if” command, like this: if (this happens) { You can also layer these so that you have integral command sections inside integral command sections. For example: if (this happens) { play_sound("Stalingrad2.wav"); NOTE: Our timer has expired, and the first Russian attack on the German positions can now happen. The timer is an example of a “trigger.” A trigger basically means, “X will happen in the game when Y happens first.” So now that X has happened (the 20 seconds of the russian_attack1 timer are up, we can play some dramatic music to go along with the attack. The Stalingrad2.wav file is in the same file as the scenario, so it plays. popup_dialog("Here they come! To arms!"); NOTE: As a further signal to the German player, a popup_dialog box comes up on the screen and warns the player that the Russians are coming, so get ready! create_unit(1,101,136,"Shock Infantry",10); NOTE: The create_unit command is another very important command. This command basically says, “Create units (for Player 1 set_explored(2,79,135,20); NOTE: I wanted the player to see some of the Russians that were coming, for fun, in an area of the map that is typically not visible. This command basically says, “Make this part of the map explored (visible to Player 2, these X, Y coordinates, 20 game tile radius surrounding those X, Y coordinates).” That part of the map will become explored, meaning it will become visible for a few seconds. for (a3=num_type(1,"Shock Infantry"); a3> NOTE: This list of instructions is hugely important, so you should remember it. What it does is basically: for (a3=num_type(1,"Shock Infantry"); a3> NOTE: For each Shock Infantry unit belonging to Player 1 and execute the following commands … rus3=find_unit(1,"Shock Infantry"); NOTE: Set a variable (rus3) and define it as a “Shock Infantry” unit belonging to Player 1 … unit_stance_order(1,rus3,"Aggressive"); NOTE: Set the stance of the unit defined as “rus3” belonging to Player as “Aggressive” … unit_move_order(1,rus3,64,135); NOTE: Tell the unit defined as “rus3” belonging to Player 1 to move to map coordinates 64, 135. By telling the Russians to move instead of attack towards, I was basically setting them up for a mad charge across Red Square to try to engage the Germans in hand to hand combat. Alternate commands include: unit_attack_to_order (1,rus3,64,135); NOTE: Here, I would have been saying to this unit, move towards map coordinates 64, 135, and if you see any enemies in your way, attack them. } NOTE: The ending bracket says this set of instructions is finished. Basically, we have cycled through all of Player 1’s Shock Infantry, made them aggressive, and told them to move to a specific spot on the map. } NOTE: This ending bracket says all instructions that should be executed when the timer russian_attack1 is done is now completed (we could have put more instructions in if we had wanted). Since the trigger telling this series of instructions to happen is in the run_once section, this series of instructions will only run once. Y will only happen once in the main script body because the trigger X only ran once in the run_once section. if (any_object_near_build(1,4,2,2009,10)) { NOTE: Try to outline the main script body according to questions: What conditions mean that the player wins? What conditions mean that the player loses? What happens if my army reaches a certain place on the map? Etc. NOTE: The above lines of code set up a condition for how the German player loses the game. if (any_object_near_build(1,4,2,2009,10)) { NOTE: We have set up a trigger that basically says, “If an object is near a building (units owned by Player 1, 4 units, near Player 2’s building, building #2009, within 10 game tiles of the building)”, then execute the indented commands that are inside the starting bracket { and ending bracket }. That logic can also read: “If Player 1 has at least 4 units within 10 game tiles of Player 2’s building designated as 2009 (click on the building in the Scenario Editor to see its number), then do this.” NOTE: You could also do the identity of the building differently by assigning a variable. For example: train_station = find_build(2, “Versailles”); NOTE: Find Player 2’s building “Versailles” and assign it the variable train_station. Then: if (any_object_near_build(1,4,2,train_station,10)) { NOTE: Now let’s look at the rest of it. switch_building_type(1,2,"Versailles"); NOTE: The Russians have captured the Train Station (“Versailles Wonder”) from the Germans, so the building’s ownership should be switched from the Germans (Player 2) to the Russians (Player 1). The above command basically says, “For the type of building known as ‘Versailles’, give it to Player 1 from Player 2.” play_sound("Stalingrad4.wav"); NOTE: Play some dramatic music that signals the end of the game. popup_dialog("The Soviets have captured the Train Station!"); NOTE: The German player has been told that the Russians have taken the Train Station building away from him. popup_dialog("The Red Army has blocked our advance into the city. This is an unacceptable setback to our offensive."); NOTE: The German player is told that this is bad. set_defeat_message("You have been courtmartialed!"); NOTE: When you lose the game and the end-game menu comes up, there is always a brief message. This is the defeat message. Usually, it is a generic message but you can customize it to fit your scenario. Here, we told the German player, as the game ends, that he has been court-martialed for losing the Train Station. defeat(2); NOTE: Player 2 is defeated. The game is over. NOTE: By now, you should be following the basic logic of a scenario. You have the overall command layer: scenario { } Inside that you have basically two sections, the run_once and the main script body. The run_once section runs only once, and the main script body loops, repeating itself over and over until the game ends. scenario { run_once { if (this happens) { } Here’s another section of the Stalingrad script for the first mission that tells us we won the mission. I modified it so that it ends the game: if (num_type(1,"Shock Infantry")< NOTE: Wow, that’s a lot of code. Here’s how it breaks out: if (num_type(1,"Shock Infantry")< NOTE: This code sets up a trigger that basically says if the number of shock infantry owned by Player 1 and Player 5 is less than 10 each then do the following commands within the starting bracket { and ending bracket }. This line of code basically says, “If the number of Player 1’s Shock Infantry is less than 10 units …” You could have two conditions to be met. Say you have two players, Player 1 and Player 5, representing the Russians, fighting the German Player 1. You could make it a condition that the number of shock infantry for both player 1 and player 5 have to each be less than 10 before they lose. The code looks like this: if (num_type(1,"Shock Infantry")< NOTE: The && symbols mean “AND.” The logic looks like this: IF (this happens) AND (this also happens) THEN { Okay, so if the number of Player 1’s Shock Infantry falls below 10 units, then these commands are executed: play_sound("Stalingrad4.wav"); NOTE: Play dramatic music … popup_dialog("We have beaten back the Russian counterattack!"); NOTE: Tell the player that he has succeeded in meeting his objective. for (a16=num_type(1,"Shock Infantry"); a16> NOTE: With these lines of code we have told RON that for all of Player 1’s remaining Shock Infantry, have them move to a specific location. We could easily just tell them to move to specific X,Y coordinates. However, it would be fun to have the Russians scatter in random directions, generally heading east. This looks more realistic than all the Russians moving in the exact same direction. x=object_position_x(1,rus16); NOTE: We have designated all of Player 1’s Shock Infantry to be represented by the variable rus16. For each unit, we now find out what that unit’s X, Y coordinates are and represent these coordinates as the variables X and Y. rand1=rand_int(20,50); NOTE: The “rand_int” function is a great, fun function to use in scripting, because it creates a random number, like a dice roll in a wargame or roleplaying game. It introduces the element of chance into the scenario and makes things more fun—literally, more “dicey.” In this case, we have made up a variable called rand1 and designated that variable to be a whole number (integer) between 20 and 50. We have told it to make rand2 a number between 10 and 30. unit_move_order(1,rus16,x+rand1,y+rand2); NOTE: We have told RON to take Player 1’s Shock Infantry and make each unit move to its own X, Y coordinates plus rand1 and rand2. The logic looks like this: Say there are 2 remaining Russian units: rand1=23 rand1=41 NOTE: In another scenario, Black Hawk Down, when the Americans landed from their helicopter, the Somali civilians scattered in totally random directions. You could use the above code, and make rand1 = rand_int(-50,50). This means rand1 is a randomly selected number between negative 50 (-50) and plus 50 (+50). The Somali civilians ran both left and right, down and up. NOTE: Let’s move on: remove_objective("objective1a"); NOTE: Since Player 1 has completed his objective successfully, the objectives on the lefthand side of the screen can be removed. if (population(2)< NOTE: Now that we have established 1) the conditions for the Germans to win (reduce the Russians’ shock infantry to below 10 units, and 2) what happens as a result (the remaining Russians scatter in retreat, music plays, objectives are removed), we can now to an embedded trigger that judges our degree of victory. The logic looks like this: IF (this condition is met && this condition is met) THEN { Here’s how it breaks out: if (population(2)< NOTE: Now that we know that the German player won the mission, let’s see how well he did based on the number of casualties his forces have taken in the fight. This command adds up all German units (Player 2). The logic says, “If Player 2’s total number of units is less than 15, then …” popup_dialog("We have taken catastrophic losses. High Command is furious with you. You have not received a promotion"); NOTE: Tells the player what the consequence is of his having taken excessive casualties. set_victory_message(“You have defended the Train Station!”); NOTE: Replaces the generic victory message with a customized victory message at the end of the game. victory(2); NOTE: Declares victory for Player 2 and ends the game. The ending bracket ends the IF/THEN sequence. if (population(2)> NOTE: Same as above, but changes message based on fewer casualties, meaning the German player played a better game and is rewarded for that. The second closing bracket ends the larger IF/THEN sequence of CONDITION MET/GAME OVER. NOTE: We have now completed the following basic building blocks of our script: RUN ONCE IF (time’s up) THEN IF (Russians close to Train Station) THEN IF (Russians fall below 10 units) THEN But let’s say we want to enter in another trigger, using this logic: •Player is given a toolbar Remember, in the run_once section, we had this code, which allowed us to create our toolbar: add_objective("Command:","command1a","nosound.wav"); This is realized with the following code in the Main Script Body: if (key_down("1")) { NOTE: If the player press the “1” key on his keyboard, then the two objectives known as “command1a” and “command1b” are removed from the screen. In other words, you only get to call in an artillery mission once. rand5=rand_int(1,3); NOTE: We introduce an element of chance. If the player calls in an artillery fire mission, what kind of fire support will he get from German HQ? This line of code establishes a variable, “rand5”, and make it a whole number between 1 and 3. if (rand5 == 1) { NOTE: If the random number (rand5) is 1, then: •For Player 2, at map coordinates X, Y (13, 145), create howitzer units, 3 of them. if (rand5 == 2) { NOTE: If the random number (rand5) equals 2, then the player gets 4 howitzers firing for 45 seconds. If rand5 =3, then the player gets 6 howitzers firing for 30 seconds. The final ending bracket { says that the sequence is over: IF (key 1 pressed)/THEN choose random number/THEN based on random number, give various numbers of howitzers and firing times. if (timer_expired("wait3")) { NOTE: If the timer “wait3” expires, then the howitzers are removed. The kill_unit_type_anim command basically means: kill_unit_type_anim = kill a type of unit on the map, using a certain type of animation (2, “Howitzer”,1); = Player 2’s howitzers; the “1” designates the animation for the death; a “1” means simply erase the unit. Other choices include “stabbed,” “shot” and “exploded”.
//The 500 or so trigger functions are the primary method of accessing and manipulating game state by scripts.
//For a list of available script functions, see Edit->
//All listed functions are available for use within any script.
//Also use the Word document, “Script Functions Listing_2.doc”, for a somewhat complete listing of script functions, provided with the game or available in the forums at RON Heaven.
//========================================================== ==
//Scenario scripts are associated with a specific scenario and run every frame.
//Scenario scripts primarily rely on Triggers (can be created through Edit->
//The scenario script is accessible directly through "Edit Script" button in scenario editor.
//The script for a scenario saved in <
//See any of the scripts in ,\scenario directory for complete examples
LEARNING SCRIPTING BY ANALYZING A SCRIPT
RUN_ONCE SECTION
•Renaming unit or building types
•Renaming nations
{
//Insert commands that should be executed only once when the script is loaded here.
disable_take_attrition(2);
russians1=find_unit (1,"Shock Infantry");
set_unit_scale(1,russians1,0.7);
set_unit_type_speed("Shock Infantry",15);
set_nation_name("Germans","6th Army");
set_nation_name("Russians","62nd Army");
rename_type("Temple","Church");
rename_type("Versailles","Train Station");
rename_type("Library","Hospital");
rename_type("Senate","Cultural Center");
rename_type("Kremlin","Soviet Ministry");
rename_type("Taj Mahal","Soviet Army HQ");
rename_type("Supercollider","Tractor Factory");
rename_type("Red Fort","Red October Factory");
rename_type("Siegeship","Supply Transport");
rename_type("Ironclad","Troop Carrier");
rename_type("Patrol Boat","Troop Carrier");
rename_type("T80 Tank","T34 Tank");
rename_type("Radar Air Defense","AA Gun");
rename_type("Bomber","Heavy Bomber");
rename_type("Supply Wagon","Supply Truck");
rename_type("Artillery","Anti-Tank Gun");
zoom_in(68,139);
set_timer("russian_attack2",35);
add_objective("Objective:","objective1a","nosound.wav");
add_objective("Hold the Train Station","objective1c","nosound.wav");
add_objective(" ","objective1d","nosound.wav");
add_objective("Command:","command1a","nosound.wav");
add_objective("1 - Call in artillery strike","command1c","nosound.wav");
}
MAIN SCRIPT BODY
(then this happens);
(then this happens);
(then this happens);
}
(then this happens);
if (this happens) {
(then this happens);
(then this happens);
}
(then this happens);
(then this happens);
}
create_unit(1,105,157,"Shock Infantry",10);
rus3=find_unit(1,"Shock Infantry");
unit_stance_order(1,rus3,"Aggressive");
unit_move_order(1,rus3,64,135);
}
switch_building_type(1,2,"Versailles");
play_sound("Stalingrad4.wav");
popup_dialog("The Soviets have captured the Train Station!");
popup_dialog("The Red Army has blocked our advance into the city. This is an unacceptable setback to our offensive.");
set_defeat_message("You have been courtmartialed!");
defeat(2);
}
}
}
}
do this;
do this;
do this;
}
then do this;
then do this;
}
play_sound("Stalingrad4.wav");
popup_dialog("We have beaten back the Russian counterattack!");
for (a16=num_type(1,"Shock Infantry"); a16>
rus16=find_unit(1,"Shock Infantry");
x=object_position_x(1,rus16);
y=object_position_y(1,rus16);
rand1=rand_int(20,50);
rand2=rand_int(10,30);
unit_move_order(1,rus16,x+rand1,y+rand2);
}
remove_objective("objective1a");
remove_objective("objective1b");
remove_objective("objective1c");
remove_objective("objective1d");
remove_objective("command1a");
remove_objective("command1b");
remove_objective("command1c");
remove_objective("command1d");
if (population(2)<
popup_dialog("We have taken catastrophic losses. High Command is furious with you. You have not received a promotion");
set_victory_message(“You have defended the Train Station!”);
victory(2);
}
if (population(2)>
popup_dialog("You have fought very well. You have been promoted!");
set_victory_message(“Well done!”);
victory(2);
}
}
DO THIS;
AFTER THAT, THEN DO THIS;
AFTER THAT, THEN DO THIS;
}
rus16=find_unit(1,"Shock Infantry");
x=object_position_x(1,rus16);
y=object_position_y(1,rus16);
rand1=rand_int(20,50);
rand2=rand_int(10,30);
unit_move_order(1,rus16,x+rand1,y+rand2);
}
y=object_position_y(1,rus16);
rand2=rand_int(10,30);
}
rand2=15
Unit 1 ->
Unit 1 will now move to 53, 165 (30+23, 150+15)
rand2=24
Unit 2 ->
Unit 2 will now move to 76, 169 (35+41,145+24)
remove_objective("objective1b");
remove_objective("objective1c");
remove_objective("objective1d");
remove_objective("command1a");
remove_objective("command1b");
remove_objective("command1c");
remove_objective("command1d");
popup_dialog("We have taken catastrophic losses. High Command is furious with you. You have not received a promotion");
set_victory_message(“You have defended the Train Station!”);
victory(2);
}
DO THIS;
THEN DO THIS;
IF (this condition is met) THEN {
DO THIS;
DO THIS;
}
}
}
popup_dialog("You have fought very well. You have been promoted!");
set_victory_message(“Well done!”);
victory(2);
}
}
RUSSIANS ATTACK
PLAYER 1 LOSES
PLAYER 1 WINS
•If you press “1”, you get to fire long-range artillery
•When you press 1, it’s random what kind of artillery you get, and the artillery lasts only a certain amount of time before disappearing
add_objective("1 - Call in artillery strike","command1b","nosound.wav");
remove_objective("command1a");
remove_objective("command1b");
create_unit(2,13,145,"Howitzer", 3);
jump_camera(17,149);
popup_dialog("This fire mission will last 60 seconds. Prepare to fire!");
jump_camera(68,139);
set_timer("wait3",67);
}
•Move the game “camera” to map coordinates 17, 149. The player’s view will jump to that spot so he can see that the howitzers have been created.
•The player is told that the fire mission will last 60 seconds. He sees that he has been given 3 howitzers.
•A timer has been established. At the end of 67 seconds, the howitzers will be removed (see later code below). We give the player 67 seconds instead of 60 because it takes a few seconds for the newly created howitzers to “unpack”.
create_unit(2,13,145,"Howitzer", 4);
jump_camera(17,149);
popup_dialog("This fire mission will last 45 seconds. Prepare to fire!");
jump_camera(68,139);
set_timer("wait3",52);
}
if (rand5 == 3) {
create_unit(2,13,145,"Howitzer", 6);
jump_camera(17,149);
popup_dialog("This fire mission will last 30 seconds. Prepare to fire!");
jump_camera(68,139);
set_timer("wait3",37);
}
}
kill_unit_type_anim(2,"Howitzer",1);
}