FritzBot Buttons And Levers

From Bots-United Wiki

Jump to: navigation, search

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	
 }

Permanent link to this page

Retrieved from "FritzBot_Buttons_And_Levers"