Paththrough UseSwitch
Paththrough Main Page | Paththrough UseSwitch |
UseSwitch
The UseSwitch type of paththrough is typically used for enabling bots to press switches or buttons that open doors or call elevators along their way. It requires a Switches table in the map script, similar to the following example:
Map =
{
Door1Status = 0, //door is closed initially
Switches =
{
door1 =
{
Enabled = true,
Priority = 0, //always set to 0 when using path through
WaypointName = "door_1switch",
Timeout = 3000,
AimPosition = Vec3(-4552.238, -6960.125, 4064.353), // use /bot aim_pos to get aim vector. Replaces the unreliable waypoint facing.
ExitConditions = // optional. used to continue to press the button until exit conditions are true
{
f = function(bot)
{
return Map.Door1Status > 0; // return true to stop pressing the button
}
},
Wait = function() // optional. used to have the bot wait a bit for slow moving doors / elevators
{
return Map.Door1Status == 2; // return true to finish the paththrough and go through the door
},
},
},
};
In order for the goal to be used, a paththrough property must be set on a waypoint that the bots will reach as part of the path going to a destination beyond the switch. In this example, the goal is UseSwitch_PT and the switch to be used is door1 ( from the switch table ):
/bot waypoint_setproperty paththrough UseSwitch_PT:door1
Script and waypoints should be set up similarly to the old useswitch goal from Omni-bot 0.71, except that there can be ExitConditions and a Wait() function in the table for each switch, and Priority should be set to 0. Availability of the switch should be set similarly to the normal useswitch goal as well
Door1_Moving = function ( trigger )
{
if ( trigger.Action == "opening" )
{
Map.Door1Status = 1; //opening
sleep(1.5); //wait 1.5 seconds while the door is opening
Map.Door1Status = 2; //opened
Map.Switches.door1.Enabled = false;
}
else
{
Map.Door1Status = 0; //closed
Map.Switches.door1.Enabled = true;
}
},
Note that the switch is disabled after the door opens, so bots will stop pressing it.
In the following example image, the command
/bot waypoint_setproperty paththrough UseSwitch_PT:door1
was used at waypoint A. Now a bot that is trying to reach waypoint B via A is instructed to go to waypoint C (named "door_1switch") and press the switch S. Once the door starts opening, the bot stops pressing the switch because ExitConditions return true, waits 1.5 seconds to give the door time to open properly, and then moves on normally.
Note that the use of one-way connections between waypoints is often required when using paththrough. In our example, the bots would otherwise unnecessarily use the switch when passing waypoint A from the opposite direction. Also, it is important that A and B don't have the blockwall flag set, because the bots would consider the unidirectional path from A to B blocked and hence unusable if that flag were used.
The same basic principle can be applied to elevators. In the following two images, there is a one-way connection leading from waypoint A to waypoint B on the next floor (not visible). Again, the paththrough property set on waypoint A makes the bot press the switch S, rather than trying to move towards B directly.
In the above example, the command applied to waypoint A could typically read
/bot waypoint_setproperty paththrough UseSwitch_PT:elevator
In the below example, there are 2 floors and 4 switches - inside and outside the elevator.
Switches =
{
// /bot waypoint_setproperty paththrough UseSwitch_PT:lift_bottom_out
lift_bottom_out =
{
AimPosition = Vec3(1830.403, 1493.125, -63.050), ///bot aim_pos
Enabled = false,
Priority = 0,
WaypointName = "lift_bottom_out",
Timeout = 9000,
ExitConditions =
{
f = function(bot)
{
return Map.LiftIsMovingDown;
}
},
Wait = function()
{
return !Map.LiftIsMovingDown;
},
},
// /bot waypoint_setproperty paththrough UseSwitch_PT:lift_bottom_ins
lift_bottom_ins =
{
AimPosition = Vec3(1836.532, 1479.875, -44.111), ///bot aim_pos
Enabled = true,
Priority = 0,
WaypointName = "lift_bottom_ins",
Timeout = 6000,
Wait = function()
{
return Map.Lift_is_up;
},
},
// /bot waypoint_setproperty paththrough UseSwitch_PT:lift_up_out
lift_up_out =
{
AimPosition = Vec3(1830.124, 1492.125, 144.047), ///bot aim_pos
Enabled = true,
Priority = 0,
WaypointName = "lift_up_out",
Timeout = 9000,
ExitConditions =
{
f = function(bot)
{
return Map.LiftIsMovingUp;
}
},
Wait = function()
{
return !Map.LiftIsMovingUp;
},
},
// /bot waypoint_setproperty paththrough UseSwitch_PT:lift_up_ins
lift_up_ins =
{
AimPosition = Vec3(1838.358, 1479.875, 143.522), ///bot aim_pos
Enabled = false,
Priority = 0,
WaypointName = "lift_up_ins",
Timeout = 6000,
Wait = function()
{
return Map.Lift_is_down;
},
},
},
Lift_is_moving = function( trigger )
{
vel = ToVector(trigger.Action);
if ( vel.z > 0 )
{
Util.MapDebugPrint( "Lift goes up", true );
Map.LiftIsMovingUp = true;
Map.Lift_is_down = false;
Map.Switches.lift_bottom_out.Enabled = true;
Map.Switches.lift_bottom_ins.Enabled = false;
sleep(2.3);
Map.Lift_is_up = true;
sleep(1); //wait to bots leave lift
Map.LiftIsMovingUp = false;
Map.Switches.lift_up_out.Enabled = false;
Map.Switches.lift_up_ins.Enabled = true;
}
if ( vel.z < 0 )
{
Util.MapDebugPrint( "Lift goes down", true );
Map.LiftIsMovingDown = true;
Map.Lift_is_up = false;
Map.Switches.lift_up_out.Enabled = true;
Map.Switches.lift_up_ins.Enabled = false;
sleep(2.3);
Map.Lift_is_down = true;
sleep(1); //wait to bots leave lift
Map.LiftIsMovingDown = false;
Map.Switches.lift_bottom_out.Enabled = false;
Map.Switches.lift_bottom_ins.Enabled = true;
}
}