FritzBot Buttons And Levers
From Bots-United Wiki
Intro
FritzBot button and lever support was never completed. Only a very few maps that use func_doors as buttons or levers can therefore be supported directly (by making the bots temporarily want to pass through the "door"). Most maps use other entity types (like func_button etc.) that the bots do not understand. However with ETPro map scripting and the power of the FritzBot ET AI script system, it is possible to have the bots use them 'intelligently'. This page will just provide an example from Adlernest to show the setup. Before attempting to understand or use the example, reading and understanding the Fritzbot_Map_Scripting page is highly recommended.
Scenario
Adlernest has two levers that control one door. The door is used as a line of defense for the Axis by the transmitter when closed. When opened, the doorway gives the Allies another route to help clear the area and transmit the documents. In setting up the levers, the Axis bots should only close the door and the Allied bots should only open the door.
Setup
The first thing to do is setup the entities we will be using. The bots can't really use the levers or buttons, but we can place a location trigger with ETPro Map scripting to simulate the usage:
//crapshoot: create some location triggers for the levers //allies trigger at stairs lever create { spawnflags "2" //allies only scriptName "push_lever1" classname "trigger_multiple" targetname "push_lever1" target "open_script_trigger" origin "901 -2863 -111" } //axis trigger at stairs lever create { spawnflags "1" //axis only scriptName "push_lever2" classname "trigger_multiple" targetname "push_lever2" target "close_script_trigger" origin "901 -2863 -111" } //allies trigger near transmitter lever create { spawnflags "2" //allies only scriptName "push_lever3" classname "trigger_multiple" targetname "push_lever3" target "open_script_trigger" origin "424 -3696 -95" } //axis trigger near transmitter lever create { spawnflags "1" //axis only scriptName "push_lever4" classname "trigger_multiple" targetname "push_lever4" target "close_script_trigger" origin "424 -3696 -95" }
The next step is to create the entities that our location triggers target. The entities used are target_script_trigger entities:
// these next two run the scripts that open and close the doors // open the door create { scriptName "open_script_trigger" classname "target_script_trigger" targetname "open_script_trigger" target "run" origin "2749 -1533 -55" } // close the door create { scriptName "close_script_trigger" classname "target_script_trigger" targetname "close_script_trigger" target "run" origin "2749 -1533 -55" }
We are going to need to interact with the aiscript, so we will need some helper entities as well:
// need some helpers to interact with the aiscript //first one will be for door opening create { objflags "2" scriptName "helper_ent_obj" classname "trigger_objective_info" targetname "helper_ent_obj" target "helper_ent" origin "2749 -1533 -55" mins "-63 -10 0" maxs "63 10 128" health 1000000 //spawnflags 17 // AXIS_OBJECTIVE(1) | CUSTOMIMAGE track "helper_ent" shortname "helper_ent" //eflags 65536 //customaxisimage "gfx/limbo/cm_radar_maindoor" //model "*16" } create { classname "func_constructible" spawnflags "4" scriptname "helper_ent" targetname "helper_ent" origin "2749 -1533 -55" mins "-63 -10 0" maxs "63 10 128" eflags 65536 svflags 1 model "*24" } //second one will be for door closing create { objflags "2" scriptName "helper_ent_obj2" classname "trigger_objective_info" targetname "helper_ent_obj2" target "helper_ent2" origin "41 1597 583" mins "-63 -10 0" maxs "63 10 128" health 1000000 //spawnflags 17 // AXIS_OBJECTIVE(1) | CUSTOMIMAGE track "helper_ent2" shortname "helper_ent2" //eflags 65536 //customaxisimage "gfx/limbo/cm_radar_maindoor" //model "*16" } create { classname "func_constructible" spawnflags "4" scriptname "helper_ent2" targetname "helper_ent2" origin "41 1597 583" mins "-63 -10 0" maxs "63 10 128" eflags 65536 svflags 1 model "*24" }
The next step is to give the target_script_trigger entities something to do:
//crapshoot: to use levers open_script_trigger //open the blast doors { spawn { wait 200 } trigger run //run is the 'target' of the target_script_trigger { //make sure it only triggers once until its ready again globalaccum 7 abort_if_not_equal 0 globalaccum 7 set 1 //ok, made it here, open em trigger maindoorr move_up trigger maindoorl move_up } } close_script_trigger //close the blast doors { spawn { wait 200 } trigger run //run is the 'target' of the target_script_trigger { //make sure it only triggers once until its ready again globalaccum 5 abort_if_not_equal 0 globalaccum 5 set 1 //ok, made it here, so close em trigger maindoorr move_down trigger maindoorl move_down } }
Notice the globalaccum's. They are to make sure the location trigger only triggers once. They need to be set first in the game_manager block:
//crapshoot: main door is closing globalaccum 7 set 0 //crapshoot: main door is opening globalaccum 5 set 0 //cannot use 8, ET bug
The next step is to call our aiscript and update the globalaccum's:
maindoorl { spawn { wait 200 gotomarker maindoorl_pc2 1000 } trigger move_up { // open // abort if working or opened accum 5 abort_if_equal 2 accum 5 abort_if_equal 1 // set status working accum 5 set 2 // let our aiscript know too construct helper_ent wm_announce "Main blast door opening!" wait 500 playsound sound/movers/misc/big_gate1.wav wait 400 playsound sound/movers/misc/big_gate2.wav looping forever gotomarker maindoorl_pc1 45 wait stopsound playsound sound/movers/misc/big_gate3.wav // set status opened accum 5 set 1 // crapshoot: let our location trigger know too globalaccum 5 set 0 } trigger move_down { // close // abort if working or closed accum 5 abort_if_equal 2 accum 5 abort_if_equal 0 // set status working accum 5 set 2 // let our aiscript know too construct helper_ent2 wm_announce "Main blast door closing!" wait 500 playsound sound/movers/misc/big_gate1.wav wait 400 playsound sound/movers/misc/big_gate2.wav looping forever gotomarker maindoorl_pc2 45 wait stopsound playsound sound/movers/misc/big_gate3.wav // set status closed accum 5 set 0 // crapshoot: let our location trigger know too globalaccum 7 set 0 } }
Lastly, the helper_ents need to be put in the aiscript:
action 0 //helper_ent door opening { //set the status activateAction 6 //this is an action_invalid. if_action_true just tests goal_number //connect the nodes node_connect 56 323 true //only do the following if the docs have been grabbed //activate the axis lever actions //wait until the lever can be used if_obj_home_false 29 wait 7 activateAction_Group 5 //deactivate the axis transmitter actions if_obj_home_false 29 wait 7 deactivateAction_Group 3 //deactivate the allied lever actions if_obj_home_false 29 deactivateAction_Group 6 //activate the allied transmitter actions if_obj_home_false 29 activateAction_Group 4 } action 1 //helper_ent door closing { //set the status deactivateAction 6 //this is an action_invalid. if_action_true just tests goal_number //disconnect the nodes node_disconnect 56 323 true //only do the following if the docs have been grabbed //activate the allies lever actions //wait until the lever can be used if_obj_home_false 29 wait 7 activateAction_Group 6 //make the levers the only allied actions available if_obj_home_false 29 wait 7 deactivateAction_Group 4 //deactivate the axis lever actions if_obj_home_false 29 deactivateAction_Group 5 //activate the axis transmitter actions if_obj_home_false 29 activateAction_Group 3 }
Notice the use of action_invalid (action number 6). Because if_action_true / false just checks the goal number of the action, we can set the 'status' of the door by activating or deactivating it. With the status set, when changing phases we can decide whether a particular team should go for the levers or the regular actions:
action 29 //documents { //move to the next phase //choose which actions to go for based on door status //if_action_true just tests goal_number and I activate / deactivate action 6 in the helper tests //door is closed, allies should go for the levers if_obj_home_false 29 AND if_action_true 6 activateAction_Group 6 //door is closed, axis should set up basic defense if_obj_home_false 29 AND if_action_true 6 activateAction_Group 3 //door is open, allies should set up basic defense if_obj_home_false 29 AND if_action_false 6 activateAction_Group 4 //door is open, axis should go for the levers if_obj_home_false 29 AND if_action_false 6 activateAction_Group 5 //deactivate the axis document defense on the steal if_obj_home_false 29 deactivateAction_Group 2 //activate the axis document defense if its returned if_obj_home_true 29 activateAction_Group 2 //clean up all the actions by transmitter if_obj_home_true 29 deactivateAction_Group 3 if_obj_home_true 29 deactivateAction_Group 4 if_obj_home_true 29 deactivateAction_Group 5 if_obj_home_true 29 deactivateAction_Group 6 }