Merge pull request 'Make bots drift' (#47) from Anonimus/blankart:dobotsdrift into blankart-dev
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/47
This commit is contained in:
commit
b3922d1316
12 changed files with 373 additions and 6 deletions
|
|
@ -5214,6 +5214,10 @@ thingtypes
|
|||
title = "Waypoint Anchor";
|
||||
sprite = "WAY2A0";
|
||||
angletext = "ID";
|
||||
flags1text = "[1] Powerslide";
|
||||
flags4text = "[4] Drift left";
|
||||
flags8text = "[8] Drift right";
|
||||
parametertext = "End drift";
|
||||
fixedrotation = 1;
|
||||
}
|
||||
2004
|
||||
|
|
|
|||
|
|
@ -5374,6 +5374,20 @@ udmf
|
|||
8 = "Finish line";
|
||||
}
|
||||
}
|
||||
arg3
|
||||
{
|
||||
title = "Drifting";
|
||||
type = 11;
|
||||
enum
|
||||
{
|
||||
0 = "No action";
|
||||
1 = "Left powerslide";
|
||||
2 = "Left drift";
|
||||
3 = "Right powerslide";
|
||||
4 = "Right drift";
|
||||
5 = "End drift";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2004
|
||||
|
|
|
|||
|
|
@ -402,6 +402,17 @@ typedef enum
|
|||
// for kickstartaccel
|
||||
#define ACCEL_KICKSTART (TICRATE)
|
||||
|
||||
// Minimum percentage for a (non-auto) drift to begin.
|
||||
#define BOTDRIFTPERCENT (10)
|
||||
|
||||
// Minimum turning percentage for an auto drift to begin.
|
||||
#define DRIFTSTARTPCT (45)
|
||||
|
||||
#define DRIFTTICMUL (43690) // FRACUNIT * 0.66
|
||||
#define BOTDRIFTTICS (FixedMul(TICRATE, DRIFTTICMUL))
|
||||
|
||||
#define MAXDRIFTSKILL (FRACUNIT/2)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BOT_STYLE_NORMAL,
|
||||
|
|
@ -411,6 +422,13 @@ typedef enum
|
|||
BOT_STYLE__MAX
|
||||
} botStyle_e;
|
||||
|
||||
typedef enum {
|
||||
DRIFTSTATE_AUTO=0,
|
||||
DRIFTSTATE_ACTIVE,
|
||||
DRIFTSTATE_ENDING,
|
||||
NUMDRIFTSTATES
|
||||
} botdrift_t;
|
||||
|
||||
// player_t struct for all bot variables
|
||||
struct botvars_t
|
||||
{
|
||||
|
|
@ -429,6 +447,14 @@ struct botvars_t
|
|||
SINT8 turnconfirm; // Confirm turn direction
|
||||
UINT32 respawnconfirm; // Confirm when respawn is needed.
|
||||
|
||||
// Drift-relevant data below:
|
||||
fixed_t driftskill; // The bot's "skill" at drifts.
|
||||
// Determines how soon a bot starts to drift.
|
||||
INT32 driftstate; // Drifting state
|
||||
INT32 driftamt; // Turning severity for a drift
|
||||
SINT8 driftturn; // Drifting turn direction
|
||||
tic_t drifttime; // Time spent drifting
|
||||
boolean powersliding; // Are we powersliding?
|
||||
};
|
||||
|
||||
struct sonicloopcamvars_t
|
||||
|
|
|
|||
|
|
@ -2617,6 +2617,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
p->botvars.rubberband = FRACUNIT;
|
||||
p->botvars.controller = UINT16_MAX;
|
||||
p->botvars.driftskill =
|
||||
FixedMul(MAXDRIFTSKILL, K_BotDetermineDriftSkill(p));
|
||||
p->botvars.driftstate = DRIFTSTATE_AUTO;
|
||||
|
||||
if (follower)
|
||||
P_RemoveMobj(follower);
|
||||
|
|
|
|||
214
src/k_bot.cpp
214
src/k_bot.cpp
|
|
@ -1035,6 +1035,147 @@ static void K_DrawPredictionDebug(botprediction_t *predict, const player_t *play
|
|||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
fixed_t K_BotDetermineDriftSkill(player_t *player)
|
||||
|
||||
Calculates drift skill for a player based on stats.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to get drift skill for.
|
||||
|
||||
Return:-
|
||||
Calculated drift skill.
|
||||
--------------------------------------------------*/
|
||||
fixed_t K_BotDetermineDriftSkill(player_t *player)
|
||||
{
|
||||
return ((FRACUNIT * (player->kartspeed + player->kartweight)) / 18);
|
||||
}
|
||||
|
||||
static void K_WaypointGetDirectionVector(waypoint_t *wp1, waypoint_t *wp2, vector3_t *a_o)
|
||||
{
|
||||
vector3_t v1, v2;
|
||||
|
||||
v1.x = wp1->mobj->x;
|
||||
v1.y = wp1->mobj->y;
|
||||
v1.x = wp1->mobj->z;
|
||||
|
||||
v2.x = wp2->mobj->x;
|
||||
v2.y = wp2->mobj->y;
|
||||
v2.x = wp2->mobj->z;
|
||||
|
||||
FV3_SubEx(&v1,&v2,a_o);
|
||||
FV3_Normalize(a_o);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static INT32 K_BotStartDrift(player_t* player)
|
||||
|
||||
Begins and ends "forced" drifts on a per-waypoint basis.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to begin the drift for.
|
||||
|
||||
Return:-
|
||||
Override value for turn amount.
|
||||
--------------------------------------------------*/
|
||||
static INT32 K_BotStartDrift(player_t* player)
|
||||
{
|
||||
// Handle DRIFTING towards waypoints!
|
||||
boolean shouldDrift;
|
||||
fixed_t botDriftSpeed, distToNext;
|
||||
INT32 driftsetting, turnamt;
|
||||
|
||||
if ((!(player->currentwaypoint)) ||
|
||||
(!(player->currentwaypoint->driftsettings)))
|
||||
{
|
||||
// No waypoints, nothing we can do here.
|
||||
return 0;
|
||||
}
|
||||
|
||||
turnamt = 0;
|
||||
driftsetting = player->currentwaypoint->driftsettings;
|
||||
botDriftSpeed = FixedMul(K_GetKartSpeed(player, false, false),
|
||||
FixedPercentage(BOTDRIFTPERCENT));
|
||||
|
||||
if (((driftsetting)) &&
|
||||
(driftsetting <= DRIFT_END))
|
||||
{
|
||||
shouldDrift = false;
|
||||
|
||||
// Randomly decide to drift based on our skill at drifting,
|
||||
// and how fast we're moving.
|
||||
fixed_t driftpotential = P_RandomKey(MAXDRIFTSKILL);
|
||||
|
||||
if ((driftpotential <= player->botvars.driftskill) &&
|
||||
(botDriftSpeed <= player->speed))
|
||||
{
|
||||
{
|
||||
// Get our distance from the waypoint.
|
||||
distToNext = R_PointToDist2(
|
||||
0,
|
||||
player->mo->z,
|
||||
R_PointToDist2(player->mo->x,
|
||||
player->mo->y,
|
||||
player->currentwaypoint->mobj->x,
|
||||
player->currentwaypoint->mobj->y),
|
||||
player->currentwaypoint->mobj->z);
|
||||
|
||||
// If we're within distance, start drifting!
|
||||
if (distToNext < player->currentwaypoint->mobj->radius)
|
||||
{
|
||||
shouldDrift = true;
|
||||
turnamt = KART_FULLTURN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDrift)
|
||||
{
|
||||
// Start our drift based on the waypoint's drift settings.
|
||||
switch (driftsetting)
|
||||
{
|
||||
case DRIFT_PWRSLIDE_L:
|
||||
player->botvars.driftstate = DRIFTSTATE_ACTIVE;
|
||||
player->botvars.driftturn = -1;
|
||||
player->botvars.powersliding = true;
|
||||
break;
|
||||
case DRIFT_LEFT:
|
||||
player->botvars.driftstate = DRIFTSTATE_ACTIVE;
|
||||
player->botvars.driftturn = -1;
|
||||
player->botvars.powersliding = false;
|
||||
break;
|
||||
case DRIFT_PWRSLIDE_R:
|
||||
player->botvars.driftstate = DRIFTSTATE_ACTIVE;
|
||||
player->botvars.driftturn = 1;
|
||||
player->botvars.powersliding = true;
|
||||
turnamt *= -1;
|
||||
break;
|
||||
case DRIFT_RIGHT:
|
||||
player->botvars.driftstate = DRIFTSTATE_ACTIVE;
|
||||
player->botvars.driftturn = 1;
|
||||
player->botvars.powersliding = false;
|
||||
turnamt *= -1;
|
||||
break;
|
||||
case DRIFT_END:
|
||||
if (player->botvars.driftstate)
|
||||
{
|
||||
player->botvars.driftstate = DRIFTSTATE_ENDING;
|
||||
player->botvars.driftturn = 0;
|
||||
player->botvars.powersliding = false;
|
||||
turnamt = INT32_MAX; // Tells the game not to modify turning.
|
||||
}
|
||||
break;
|
||||
case DRIFT_NONE:
|
||||
default:
|
||||
turnamt = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return turnamt;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static INT32 K_HandleBotTrack(const player_t *player, ticcmd_t *cmd, botprediction_t *predict)
|
||||
|
||||
|
|
@ -1053,7 +1194,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
|
|||
ZoneScoped;
|
||||
|
||||
// Handle steering towards waypoints!
|
||||
INT32 turnamt = 0;
|
||||
INT32 turnamt = 0, driftamt = 0;
|
||||
SINT8 turnsign = 0;
|
||||
angle_t moveangle;
|
||||
INT32 anglediff;
|
||||
|
|
@ -1080,6 +1221,9 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
|
|||
// Wrong way!
|
||||
cmd->forwardmove = -MAXPLMOVE;
|
||||
cmd->buttons |= BT_BRAKE;
|
||||
|
||||
// Why would we need to drift?
|
||||
cmd->buttons &= ~(BT_DRIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1097,6 +1241,13 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
|
|||
realrad = playerwidth;
|
||||
}
|
||||
|
||||
// Nonesensical and hacky. Figure out a better way eventually.
|
||||
fixed_t turnpower =
|
||||
FRACUNIT -
|
||||
FixedMul(
|
||||
FRACUNIT,
|
||||
FixedDiv(std::max<angle_t>(0, ANGLE_90 - anglediff), ANGLE_90));
|
||||
|
||||
// Become more precise based on how hard you need to turn
|
||||
// This makes predictions into turns a little nicer
|
||||
// Facing 90 degrees away from the predicted point gives you 0 radius
|
||||
|
|
@ -1130,6 +1281,33 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
|
|||
// Going the right way, don't turn at all.
|
||||
turnamt = 0;
|
||||
}
|
||||
|
||||
// Start or continue a drift.
|
||||
if (player->botvars.drifttime)
|
||||
{
|
||||
// Confirm our drift angle.
|
||||
if ((player->botvars.driftturn)
|
||||
&& (player->botvars.drifttime < 4))
|
||||
{
|
||||
turnamt = KART_FULLTURN * -player->botvars.driftturn;
|
||||
}
|
||||
|
||||
cmd->buttons |= BT_DRIFT;
|
||||
}
|
||||
else if ((turnamt) && (player->botvars.driftstate == DRIFTSTATE_AUTO) &&
|
||||
(turnpower > FixedPercentage(DRIFTSTARTPCT)))
|
||||
{
|
||||
// TODO: Figure out a drift prediction system.
|
||||
}
|
||||
else if ((player->botvars.driftamt < 2) && (player->botvars.driftstate))
|
||||
{
|
||||
cmd->buttons |= BT_DRIFT;
|
||||
|
||||
if (player->botvars.driftamt != INT32_MAX)
|
||||
{
|
||||
turnamt = driftamt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return turnamt;
|
||||
|
|
@ -1567,6 +1745,40 @@ void K_UpdateBotGameplayVars(player_t *player)
|
|||
|
||||
player->botvars.respawnconfirm = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Figure out if we need to drift.
|
||||
// Drift-ending waypoints will kill the drift timer,
|
||||
// so no need to worry about doing that ourselves.
|
||||
player->botvars.driftamt = K_BotStartDrift(player);
|
||||
|
||||
if (player->botvars.drifttime)
|
||||
{
|
||||
// Continue the drift until we go over the threshold.
|
||||
// Only increment when we're finishing our drift, or
|
||||
// just starting it!
|
||||
if (((player->botvars.driftstate == DRIFTSTATE_ENDING) ||
|
||||
(player->botvars.driftstate == DRIFTSTATE_AUTO)) ||
|
||||
(player->botvars.drifttime < 4))
|
||||
{
|
||||
player->botvars.drifttime++;
|
||||
}
|
||||
|
||||
if (player->botvars.drifttime > BOTDRIFTTICS + 3)
|
||||
{
|
||||
player->botvars.drifttime = 0;
|
||||
player->botvars.driftstate = DRIFTSTATE_AUTO;
|
||||
}
|
||||
}
|
||||
else if ((player->botvars.driftamt) && (player->botvars.driftstate))
|
||||
{
|
||||
if (player->botvars.driftamt != INT32_MAX)
|
||||
{
|
||||
// Ready to drift!
|
||||
player->botvars.drifttime++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
K_UpdateBotGameplayVarsItemUsage(player);
|
||||
}
|
||||
|
|
|
|||
14
src/k_bot.h
14
src/k_bot.h
|
|
@ -376,6 +376,20 @@ void K_UpdateBotGameplayVars(player_t *player);
|
|||
|
||||
void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt);
|
||||
|
||||
/*--------------------------------------------------
|
||||
fixed_t K_BotDetermineDriftSkill(player_t *player)
|
||||
|
||||
Calculates drift skill for a player based on stats.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to get drift skill for.
|
||||
|
||||
Return:-
|
||||
Calculated drift skill.
|
||||
--------------------------------------------------*/
|
||||
|
||||
fixed_t K_BotDetermineDriftSkill(player_t *player);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -2198,6 +2198,12 @@ static waypoint_t *K_SetupWaypoint(mobj_t *const mobj)
|
|||
thiswaypoint->onaline = K_GetWaypointIsOnLine(thiswaypoint);
|
||||
}
|
||||
|
||||
// Set drift settings.
|
||||
if (mobj->watertop)
|
||||
{
|
||||
thiswaypoint->driftsettings = mobj->watertop;
|
||||
}
|
||||
|
||||
if (thiswaypoint->numnextwaypoints > 0)
|
||||
{
|
||||
waypoint_t *nextwaypoint = NULL;
|
||||
|
|
@ -2959,12 +2965,23 @@ static boolean K_AnchorWaypointRadius(
|
|||
{
|
||||
if (anchor->spawnpoint->angle == waypointmobj->spawnpoint->angle)
|
||||
{
|
||||
waypointmobj->radius = R_PointToDist2(
|
||||
waypointmobj->x, waypointmobj->y,
|
||||
anchor->x, anchor->y);
|
||||
// Let's keep drift parameters and radius modifications separate.
|
||||
|
||||
if (anchor->extravalue1)
|
||||
{
|
||||
waypointmobj->watertop = anchor->extravalue1;
|
||||
waypointmobj->spawnpoint->args[3] = waypointmobj->watertop;
|
||||
}
|
||||
else
|
||||
{
|
||||
waypointmobj->radius = R_PointToDist2(
|
||||
waypointmobj->x, waypointmobj->y,
|
||||
anchor->x, anchor->y);
|
||||
|
||||
// Keep changes for -writetextmap
|
||||
waypointmobj->spawnpoint->args[1] = waypointmobj->radius >> FRACBITS;
|
||||
}
|
||||
|
||||
// Keep changes for -writetextmap
|
||||
waypointmobj->spawnpoint->args[1] = waypointmobj->radius >> FRACBITS;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -24,6 +24,16 @@ extern "C" {
|
|||
|
||||
#define DEFAULT_WAYPOINT_RADIUS (384)
|
||||
|
||||
// "Powerslide" drifts in this context enable sliptiding.
|
||||
typedef enum {
|
||||
DRIFT_NONE=0,
|
||||
DRIFT_PWRSLIDE_L,
|
||||
DRIFT_LEFT,
|
||||
DRIFT_PWRSLIDE_R,
|
||||
DRIFT_RIGHT,
|
||||
DRIFT_END
|
||||
} driftSetting_e;
|
||||
|
||||
struct waypoint_t
|
||||
{
|
||||
mobj_t *mobj;
|
||||
|
|
@ -34,6 +44,7 @@ struct waypoint_t
|
|||
UINT32 *prevwaypointdistances;
|
||||
size_t numnextwaypoints;
|
||||
size_t numprevwaypoints;
|
||||
UINT32 driftsettings;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,19 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedDiv(fixed_t a, fixed_t b)
|
|||
return FixedDiv2(a, b);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Converts a percentage into a fixed number.
|
||||
*/
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedPercentage(INT32 percent)
|
||||
{
|
||||
return FixedDiv((percent * FRACUNIT), 100 * FRACUNIT);
|
||||
}
|
||||
|
||||
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedPercentageFloat(float fpercent)
|
||||
{
|
||||
return FixedDiv(FloatToFixed(fpercent), 100 * FRACUNIT);
|
||||
}
|
||||
|
||||
/** \brief The FixedSqrt function
|
||||
|
||||
\param x fixed_t number
|
||||
|
|
|
|||
|
|
@ -3716,6 +3716,12 @@ static void P_BouncePlayerMove(mobj_t *mo, TryMoveResult_t *result)
|
|||
mo->player->driftcharge = 0;
|
||||
}
|
||||
|
||||
// Regardless of bumpspark, tell bots to stop drifting if they bonk a wall.
|
||||
mo->player->botvars.drifttime = 0;
|
||||
mo->player->botvars.driftstate = DRIFTSTATE_AUTO;
|
||||
mo->player->botvars.driftturn = 0;
|
||||
mo->player->botvars.powersliding = false;
|
||||
|
||||
if (!cv_kartbumpspring.value || modeattacking != ATTACKING_NONE)
|
||||
{
|
||||
mo->player->pogospring = 0;
|
||||
|
|
|
|||
37
src/p_mobj.c
37
src/p_mobj.c
|
|
@ -3110,6 +3110,11 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
fixed_t top2 = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y);
|
||||
fixed_t bot2 = P_GetSectorFloorZAt(sector, mobj->x, mobj->y);
|
||||
|
||||
if (mobj->type == MT_WAYPOINT)
|
||||
{
|
||||
CONS_Printf("P_MobjCheckWater waypoint call (oh boy...)\n");
|
||||
}
|
||||
|
||||
// Default if no water exists.
|
||||
mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
|
||||
|
||||
|
|
@ -3408,6 +3413,11 @@ static void P_SceneryCheckWater(mobj_t *mobj)
|
|||
{
|
||||
sector_t *sector;
|
||||
|
||||
if (mobj->type == MT_WAYPOINT)
|
||||
{
|
||||
CONS_Printf("P_SceneryCheckWater waypoint call (oh boy...)\n");
|
||||
}
|
||||
|
||||
// Default if no water exists.
|
||||
mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
|
||||
|
||||
|
|
@ -13083,7 +13093,9 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
// lastlook is used for indicating the waypoint is a shortcut
|
||||
// extravalue1 is used for indicating the waypoint is disabled
|
||||
// extravalue2 is used for indicating the waypoint is the finishline
|
||||
// watertop is the waypoint's drift settings
|
||||
mobj->threshold = mthing->args[0];
|
||||
|
||||
mobj->movecount = tag;
|
||||
if (mthing->args[2] & TMWPF_DISABLED)
|
||||
{
|
||||
|
|
@ -13121,11 +13133,36 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
mobj->extravalue2 = 0;
|
||||
}
|
||||
|
||||
mobj->watertop = mthing->args[3];
|
||||
|
||||
// Sryder 2018-12-7: Grabbed this from the old MT_BOSS3WAYPOINT section so they'll be in the waypointcap instead
|
||||
P_SetTarget(&mobj->tracer, waypointcap);
|
||||
P_SetTarget(&waypointcap, mobj);
|
||||
break;
|
||||
}
|
||||
case MT_WAYPOINT_ANCHOR:
|
||||
{
|
||||
// Get the drift parameters from the anchor's spawnpoint.
|
||||
|
||||
// Drift left
|
||||
mobj->extravalue1 = ((mthing->options & MTF_OBJECTSPECIAL) >> 1);
|
||||
|
||||
if (mthing->options & MTF_AMBUSH)
|
||||
{
|
||||
// Drift right
|
||||
mobj->extravalue1 = ((mthing->options & MTF_AMBUSH) >> 1);
|
||||
}
|
||||
|
||||
// Powerslide offset
|
||||
mobj->extravalue1 = max(0, min(4, mobj->extravalue1 - (mthing->options & 1)));
|
||||
|
||||
if (mthing->extrainfo)
|
||||
{
|
||||
// If the parameter is set at all, this anchor ends the drift.
|
||||
mobj->extravalue1 = 5;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MT_BOTHINT:
|
||||
{
|
||||
// Change size
|
||||
|
|
|
|||
|
|
@ -376,6 +376,11 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
WRITEUINT32(save->p, players[i].botvars.itemconfirm);
|
||||
WRITESINT8(save->p, players[i].botvars.turnconfirm);
|
||||
WRITEUINT32(save->p, players[i].botvars.respawnconfirm);
|
||||
WRITEFIXED(save->p, players[i].botvars.driftskill);
|
||||
WRITEINT32(save->p, players[i].botvars.driftstate);
|
||||
WRITESINT8(save->p, players[i].botvars.driftturn);
|
||||
WRITEUINT32(save->p, players[i].botvars.drifttime);
|
||||
WRITEUINT8(save->p, players[i].botvars.powersliding);
|
||||
|
||||
WRITEFIXED(save->p, players[i].outrun);
|
||||
WRITEUINT8(save->p, players[i].outruntime);
|
||||
|
|
@ -694,6 +699,11 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
players[i].botvars.itemconfirm = READUINT32(save->p);
|
||||
players[i].botvars.turnconfirm = READSINT8(save->p);
|
||||
players[i].botvars.respawnconfirm = READUINT32(save->p);
|
||||
players[i].botvars.driftskill = READFIXED(save->p);
|
||||
players[i].botvars.driftstate = READINT32(save->p);
|
||||
players[i].botvars.driftturn = READSINT8(save->p);
|
||||
players[i].botvars.drifttime = READUINT32(save->p);
|
||||
players[i].botvars.powersliding = (boolean)READUINT8(save->p);
|
||||
|
||||
players[i].outrun = READFIXED(save->p);
|
||||
players[i].outruntime = READUINT8(save->p);
|
||||
|
|
|
|||
Loading…
Reference in a new issue