Creating a fake toi
From Bots-United Wiki
WAYPOINTING FOR VEHICLES
FritzBot's will escort or disable a moving vehicle with a slightly higher priority than regular actions. The result is that some bots will escort the vehicle, while others will use other available actions. It's randomly generated every time they receive a goal. Because of this, the waypointer has the ability to set up actions in strategic places based on where the vehicle is going. This is achieved by toggling actions on and off based on the vehicles location.
How can we detect where a moving vehicle is on a map? A moving vehicle follows a specific scripted path within the map. This path is defined by spline numbers. Once a tank gets to a spline, the map script determines whether or not the moving vehicle can keep moving. In most maps, there are barriers for the moving vehicles. When a vehicle reaches a certain spline near the barrier, the map script will remove the barrier completely from the map. With action_event_expire, we have the ability to toggle actions based on the location of the vehicle (because we know it reached the spline that 'expires' the barrier).
We can use the same principals for manipulating actions based on the vehicles location along the path using action_event_explode. To do this, we will need to create func_explosives and simply remove them when we want to.
Step 1: Finding the map script
Movable entities in a map (bridges that can be built and destroyed, command posts that are built and blown, tanks or trucks that move around the map, towers that fall), are all handled in the map script. Your map.pk3 is located in /etmain and its script is located in the "maps" folder of the map.pk3, along with some other files. Open the map.pk3 with your unzip software and find the script file. It'll have the same name as the map with a .script extension. Click on it and drag a copy to your fritzbot/maps folder. Do not remove the original from the pk3. If the fritzbot/maps folder is missing, create it first. Make sure that you have set /sv_pure = 0 so your soon-to-be modified version of the script will be used when you run the map (instead of the original in the .pk3).
You'll find that the script is full of arcane commands that are critical to the functioning of the map. DO NOT CHANGE ANYTHING EXCEPT WHAT IS DESCRIBED HERE. If you screw up, your map may not run. All is not lost, however, because you safely left the original untouched in the map.pk3, didn't you?
Step 2: Creating the fake entity
Open the map .script in your text editor. You may have to instruct Windows to accept the .script extension as a valid text file. At the very top of the file you'll see the "game_manager" and "spawn" headings with their associated curly-brackets, as shown below:
game_manager { spawn {
Scroll down until you reach the "//Game rules" comment. There may or may not be other lines of code between the top of the file and "//Games rules." The example below is from Caen2:
// Game rules wm_axis_respawntime 15 wm_allied_respawntime 30 wm_number_of_objectives 8 wm_set_round_timelimit 20 // Objectives // 1: Capture Town . . .
Now you need to insert the following script modifications JUST ABOVE the //Game rules comment (example is also from Caen2):
//Create a fake toi to detect when the tank begins to roll //note, the name fake toi is just used as a common naming convention create // The fake explode entity -- this is our signal "mine" { scriptName "faketoi1" classname "func_explosive" targetname "faketoi1" origin "-1806 -3543 402" mins "-63 -10 0" maxs "63 10 128" health "1000000" spawnflags 1 eflags 65536 svflags 1 }
Next you need to alter some of the values to suit your specific map. You can change the faketoi1 names to suit your fancy BUT BE CONSISTENT FOR THE "CREATES." Since more than one fake entity is usually necessary, using numerical suffixes help to keep additional entities from getting mixed up is recommended.
The numerical values for the "origin" parameter are the xyz map coordinates of the entities. To get these values for your map, enter the map as a player, choose a remote spot on the map and go there. Type /viewpos in the console and you'll be rewarded with your coordinates. Replace the ones from the Caen2 example with your map's values.
If you need more than one entity, copy your edited ones EXACTLY, then change the scriptName, targetname, classname, target, track, and shortname. You can keep the coordinates of the first set. For example:
create { scriptName "faketoi2" classname "func_explosive" targetname "faketoi2" origin "-1806 -3543 402" mins "-63 -10 0" maxs "63 10 128" health "1000000" spawnflags 1 eflags 65536 svflags 1 }
Insert these directly below the first set. Try to not use too many entities. Crapshoot has reported memory errors with more than five fake toi entities. If you experience problems with the number of added tois then the script changes can be structured to use other existing trigger_objective_infos (i.e. those for heath and ammo cabinets), or to share one added toi-fake construct pair. Sharing tois is not covered in this article, so if needed review Fritzbot_Map_Scripting#Fake_Construct for tips on using a toi-fake construct pair.
Step 3: Telling the script what to do with the entities
Now that we have the fake entities created, we need to be able to do something with them. The following code tells the script what to do when one of these entities is manipulated. Scroll down to the closing curly-bracket of the game_manager. It's easy to miss: try placing your cursor on the game_manager top curly-bracket, then scroll slowly down until the cursor again lines up with the first right curly-bracket you encounter. Insert the following script immediately below:
//the fake toi faketoi1 { spawn { } death { } trigger remove { remove } }
Note: This step is optional as alertentity on func_explosives will remove the entity. But it's good practice to have script blocks for any entities we create.
Notice the name “faketoi1�?. These should EXACTLY MATCH the scriptName used in the create code. The scriptName of the entity tells the game that if an event happens to that entity, it should look through the script to find these. For any additional ones you may add, you need to make sure the scriptName is the same as the corresponding script you want run. Add the additional scripts immediately below the first.
Step 4: Removing the entity
As discussed above, removing an entity causes its toi to change state, allowing an action_event_explode (action type #34) to detect it. To decide where to put the removal code, we have to identify the particular spline that corresponds to the desired location of the vehicle. To do so, scroll further downward in the script, usually a considerable distance. You'll eventually encounter a heading comment called "//TANK STUFF," closely followed by a "tank" heading and its left curly-bracket (if there is a truck, it'll say "truck" instead). Soon after, you'll begin seeing a string of "trigger run_x" code modules. These are the vehicle-movement scripts and the number "x" corresponds to the spline number.
To find out where a particular spline is on the map, insert temporary "wm_announce" commands as shown below. The wm_command text will be displayed on your screen when the vehicle reaches that spline. At every spline that you think might be of interest to you, place a wm_announce with the spline number changed to indicate the particular spline number where the wm_announce is located. Then start the game, build the vehicle, and jump on or escort it. You'll see your wm-announcements displayed as the vehicle rolls along from spline to spline. Zero in on your desired location and then insert the line of code "alertentity faketoi1" right after the trigger x_run top curly-bracket. Here is another example from Caen2:
trigger run_1 { //here is where we remove the faketoi alertentity faketoi1 //put this immediately below the top curly-bracket //we can use this to see where the splines are wm_announce "^1HELLO WAYPOINTER, I AM AT SPLINE 1" //these lines will vary between maps and between splines trigger self tracks_forward trigger game_manager axis_move_tank accum 1 bitset 2 followspline 0 spln3 50 wait length 32 accum 1 bitreset 2 trigger self run_continue }
Be sure the entity name following "alertentity" is EXACTLY the targetname of the func_explosive entity you wish to remove. When you are finished, the wm_announce entries can be removed.
Step 5: Getting the entity numbers
Now we can use our entities with action_event_explode, but first we have to find the number of these invisible entities. Enter /faketois in the console and you'll see the newly-allocated numbers of your fake entities. The console command also writes the data to the file "entities_yourmapname.txt" and places it in your \fritzbot folder.
NOTE: the addition of fake entities to the map does not use numbers from the end of the entity-number list as you would logically expect, but arbitrarily inserts them into the middle of the list somewhere. This means that many entity numbers on the map will change. Either do all your fake-entity work at the beginning of your waypointing or expect to have to recheck all of your actions' entity numbers later. Failing to do this will screw you up royally!
Step 6: Removing the entity icon from the game map
A result of creating a trigger_objective_info entity is that its icon gets added to the game map. Since this is actually an invisible object, we don't want players running all over the map looking for what seems to be a command post. To remove the icon, you have to comment out some lines in the script modifications that we have just completed. You must do this AFTER finding your entity numbers because these lines are necessary for that. Go back to your "faketoi1_obj" script and comment out the spawnflags, eflags, customaxisimage, and model lines:
create // The fake toi entity -- this is its toi { objflags "2" scriptName "faketoi1_obj" classname "trigger_objective_info" targetname "faketoi1_obj" target "faketoi1" origin "-1806 -3543 402" //same as above mins "-95 -85 0" maxs "95 85 128" //spawnflags 1 track "the Fake TOI1" shortname "Fake TOI1" //eflags 65536 //customaxisimage "gfx/limbo/cm_radar_maindoor" //model "*16" }
Note: this is only needed for entities created with the classname 'trigger_objective_info' as they are the only ones that create a command map icon.
Step 7: Using the event_explode action
The final step of the process is to place an action_event_explode node for each fake toi that you have created. The placement of these action nodes is not critical: a good place is in the air above the spline location, but it can be anywhere. Just be sure to be reasonably close to a path node or FritzBot won't allow you to create the action. The following ACTION parameters must be set (leave the remainder at their default values):
ALLIED OBJ: 34 AXIS OBJ: 34 ACTION GROUP ID: 0 ACTIVE FOREVER: 1 ACTION ENTNUM: use the entity number of the "func_explosive" entity (NOT the trigger_objective_info entity) ACTION GOAL: 0
In your aiscript, create an action test using this action. It will trigger when the vehicle reaches the spline that you have chosen. Use script keywords normally within the test to manipulate the actions that you want to change when the vehicle arrives.
That's all there is to it. Simple, eh?
Many thanks to Maleficus and Crapshoot for figuring this out! Otherwise we couldn't play any tank maps with FritzBot.