// [No-repair reset] //////////////////////////////////////////////////////////
Now, we'll make a host program that will allow users to put their cars back
upright after a crash, without repairing damage. We'll need access to the MCI
data, so we'll need the 'ISF_MCI' bit set on our flags.
We'll use another method of setting up this time around, and put what we
need inside the main settings for our program. This allows us to easily
override these settings on a per-server basis with config files.
We'll introduce another function here, 'PIE_commands' is called when a
connection types any command into chat. It is passed the command, arguments
and the UCID of the connection who called it. We'll use this to allow players
to request a reset.
In the case of resetting a car we'll need the PLID of the car to reset, but,
we have the UCID of the sender, and there can be more than one player per
connection. The function 'PIE_PLIDfromUCID' can be used to return a single
PLID value from a UCID (prioritising human players over AI), or
'PIE_PLIDsfromUCID' (plural) will return an array of all of them.
We'll add a mechanism for a delay, and make it customisable. This allows
server administrators to punish usage with a time penalty. The randomness can
be used to help thwart would-be reset-abusers.
We'll use our delay to set a callback for the flip, and then inform our user
immediately so that they don't spam the command. As we still have our UCID
from earlier, we'll use 'PIE_sayto' instead of 'PIE_say' this time so that we
don't spam the rest of the users.
Inside our flip function, we're going to use some stored helper data to find
out where our car is. Even if we don't hook the MCI packet by defining a
'PIE_MCI' function, PIE keeps a copy of the latest CompCar for each player,
indexed by PLID.
We'll add a speed check to prevent a reset being used while the car is in
motion. We're converting our raw data value to more standard units for the
sake of those who are configuring our program after us - all units are
provided in InSim.txt.
Finally, we'll send the JRR packet to reset the car with the no-repair
option. The JRR packet expects coordinates in the same scale as an autocross
object (as in an AXM packet) and ours, from the MCI packet, are in a different
scale. We'll convert our values and we'll add 1 to our Z value to lift the car
by 25cm (to ensure a safe reset in the case of a highly-damaged car). For the
heading, we'll rotate the car by 180 degrees as we scale, and make our value
safe by modding with the maximum value.
flip.php:
host.cfg: (set your own host/port/adminpass)
command line:
Now, we'll make a host program that will allow users to put their cars back
upright after a crash, without repairing damage. We'll need access to the MCI
data, so we'll need the 'ISF_MCI' bit set on our flags.
We'll use another method of setting up this time around, and put what we
need inside the main settings for our program. This allows us to easily
override these settings on a per-server basis with config files.
We'll introduce another function here, 'PIE_commands' is called when a
connection types any command into chat. It is passed the command, arguments
and the UCID of the connection who called it. We'll use this to allow players
to request a reset.
In the case of resetting a car we'll need the PLID of the car to reset, but,
we have the UCID of the sender, and there can be more than one player per
connection. The function 'PIE_PLIDfromUCID' can be used to return a single
PLID value from a UCID (prioritising human players over AI), or
'PIE_PLIDsfromUCID' (plural) will return an array of all of them.
We'll add a mechanism for a delay, and make it customisable. This allows
server administrators to punish usage with a time penalty. The randomness can
be used to help thwart would-be reset-abusers.
We'll use our delay to set a callback for the flip, and then inform our user
immediately so that they don't spam the command. As we still have our UCID
from earlier, we'll use 'PIE_sayto' instead of 'PIE_say' this time so that we
don't spam the rest of the users.
Inside our flip function, we're going to use some stored helper data to find
out where our car is. Even if we don't hook the MCI packet by defining a
'PIE_MCI' function, PIE keeps a copy of the latest CompCar for each player,
indexed by PLID.
We'll add a speed check to prevent a reset being used while the car is in
motion. We're converting our raw data value to more standard units for the
sake of those who are configuring our program after us - all units are
provided in InSim.txt.
Finally, we'll send the JRR packet to reset the car with the no-repair
option. The JRR packet expects coordinates in the same scale as an autocross
object (as in an AXM packet) and ours, from the MCI packet, are in a different
scale. We'll convert our values and we'll add 1 to our Z value to lift the car
by 25cm (to ensure a safe reset in the case of a highly-damaged car). For the
heading, we'll rotate the car by 180 degrees as we scale, and make our value
safe by modding with the maximum value.
flip.php:
<?php
function PIE_settings()
{
return array('flags' => ISF_MCI,
'maxspeed' => 0.2, // metres/second
'mindelay' => 1, // seconds, float
'maxdelay' => 3,
'insimname' => 'Flip');
}
function PIE_commands($command, $args, $ucid)
{
switch($command)
{
case 'reset':
case 'rescue':
case 'pieflip':
$PIE = PIE::connect();
$plid = PIE_PLIDfromUCID($ucid);
$mindelay = $PIE->get('PIE_settings', 'mindelay');
$maxdelay = $PIE->get('PIE_settings', 'maxdelay');
$delayrange = $maxdelay - $mindelay;
$delay = $mindelay + ((mt_rand(0,100)/100) * $delayrange);
$time = microtime(true) + $delay;
PIE_setcallback($time, 'flip', $plid);
PIE_sayto($ucid, 'flip (delayed by '.$delay.')');
}
}
function flip($plid)
{
if (empty($plid))
return false;
$PIE = PIE::connect();
$MCI = $PIE->get('PIE_MCI', $plid);
$max = $PIE->get('PIE_settings', 'maxspeed');
if (empty($MCI))
return false;
$speed = ($MCI['Speed'] / 327.68);
if ($speed > $max)
return false;
$x = round($MCI['X'] / 4096);
$y = round($MCI['Y'] / 4096);
$z = max(0, round($MCI['Z'] / 16384))+1;
$heading = (round($MCI['Heading'] / 256) + 128) % 256;
$packet = array('Type' => ISP_JRR,
'PLID' => $plid,
'JRRAction' => JRR_RESET_NO_REPAIR,
'X' => $x,
'Y' => $y,
'Zbyte' => $z,
'Flags' => 0x80,
'Heading' => $heading);
PIE_sendpacket($packet);
}
?>
flags=0
host=1.2.3.4
port=54321
adminpass=secretpassword
command line:
> pie tutorials\flip.php host.cfg