Merge branch 'master' into 22-merge-again

This commit is contained in:
Sally Coolatta 2021-04-05 01:11:26 -04:00
commit 8bb1fa57d4
27 changed files with 531 additions and 333 deletions

View file

@ -1272,43 +1272,6 @@ void D_SRB2Main(void)
if (M_CheckParm("-server") || dedicated) if (M_CheckParm("-server") || dedicated)
netgame = server = true; netgame = server = true;
if (M_CheckParm("-warp") && M_IsNextParm())
{
const char *word = M_GetNextParm();
char ch; // use this with sscanf to catch non-digits with
if (fastncmp(word, "MAP", 3)) // MAPxx name
pstartmap = M_MapNumber(word[3], word[4]);
else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number
I_Error("Cannot warp to map %s (invalid map name)\n", word);
// Don't check if lump exists just yet because the wads haven't been loaded!
// Just do a basic range check here.
if (pstartmap < 1 || pstartmap > NUMMAPS)
I_Error("Cannot warp to map %d (out of range)\n", pstartmap);
else
{
if (!M_CheckParm("-server"))
{
G_SetGameModified(true, true);
// Start up a "minor" grand prix session
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
grandprixinfo.gamespeed = KARTSPEED_NORMAL;
grandprixinfo.encore = false;
grandprixinfo.masterbots = false;
grandprixinfo.gp = true;
grandprixinfo.roundnum = 0;
grandprixinfo.cup = NULL;
grandprixinfo.wonround = false;
grandprixinfo.initalize = true;
}
autostart = true;
}
}
// adapt tables to SRB2's needs, including extra slots for dehacked file support // adapt tables to SRB2's needs, including extra slots for dehacked file support
P_PatchInfoTables(); P_PatchInfoTables();
@ -1558,13 +1521,32 @@ void D_SRB2Main(void)
if (M_CheckParm("-warp") && M_IsNextParm()) if (M_CheckParm("-warp") && M_IsNextParm())
{ {
const char *word = M_GetNextParm(); const char *word = M_GetNextParm();
pstartmap = G_FindMapByNameOrCode(word, 0); pstartmap = G_FindMapByNameOrCode(word, 0);
if (! pstartmap) if (! pstartmap)
I_Error("Cannot find a map remotely named '%s'\n", word); I_Error("Cannot find a map remotely named '%s'\n", word);
else else
{ {
if (!M_CheckParm("-server")) if (!M_CheckParm("-server"))
G_SetGameModified(multiplayer, true); {
G_SetGameModified(true, true);
// Start up a "minor" grand prix session
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
grandprixinfo.gamespeed = KARTSPEED_NORMAL;
grandprixinfo.encore = false;
grandprixinfo.masterbots = false;
grandprixinfo.gp = true;
grandprixinfo.roundnum = 0;
grandprixinfo.cup = NULL;
grandprixinfo.wonround = false;
grandprixinfo.initalize = true;
}
autostart = true; autostart = true;
} }
} }

View file

@ -428,6 +428,7 @@ consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off",
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL); consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}}; static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL); consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL);
consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL); consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);

View file

@ -88,7 +88,7 @@ extern consvar_t cv_votetime;
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop; extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize; extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize;
extern consvar_t cv_kartdebugwaypoints; extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;
extern consvar_t cv_itemfinder; extern consvar_t cv_itemfinder;

View file

@ -3658,7 +3658,6 @@ void G_StopDemo(void)
democam.soundmobj = NULL; democam.soundmobj = NULL;
democam.localangle = 0; democam.localangle = 0;
democam.localaiming = 0; democam.localaiming = 0;
democam.turnheld = false;
democam.keyboardlook = false; democam.keyboardlook = false;
if (gamestate == GS_INTERMISSION) if (gamestate == GS_INTERMISSION)

View file

@ -863,8 +863,6 @@ static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvect
INT32 localaiming[MAXSPLITSCREENPLAYERS]; INT32 localaiming[MAXSPLITSCREENPLAYERS];
angle_t localangle[MAXSPLITSCREENPLAYERS]; angle_t localangle[MAXSPLITSCREENPLAYERS];
static INT32 angleturn[2] = {KART_FULLTURN, KART_FULLTURN / 4}; // + slow turn
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
{ {
const UINT8 forplayer = ssplayer-1; const UINT8 forplayer = ssplayer-1;
@ -875,11 +873,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
const boolean gamepadjoystickmove = cv_usejoystick[forplayer].value && Joystick[forplayer].bGamepadStyle; const boolean gamepadjoystickmove = cv_usejoystick[forplayer].value && Joystick[forplayer].bGamepadStyle;
const boolean usejoystick = (analogjoystickmove || gamepadjoystickmove); const boolean usejoystick = (analogjoystickmove || gamepadjoystickmove);
static INT32 turnheld[MAXSPLITSCREENPLAYERS]; // for accelerative turning
static boolean keyboard_look[MAXSPLITSCREENPLAYERS]; // true if lookup/down using keyboard static boolean keyboard_look[MAXSPLITSCREENPLAYERS]; // true if lookup/down using keyboard
static boolean resetdown[MAXSPLITSCREENPLAYERS]; // don't cam reset every frame static boolean resetdown[MAXSPLITSCREENPLAYERS]; // don't cam reset every frame
INT32 tspeed, forward, axis; INT32 forward, axis;
joystickvector2_t joystickvector; joystickvector2_t joystickvector;
@ -887,11 +884,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
player_t *player = &players[g_localplayers[forplayer]]; player_t *player = &players[g_localplayers[forplayer]];
camera_t *thiscam = &camera[forplayer]; camera_t *thiscam = &camera[forplayer];
INT32 *th = &turnheld[forplayer];
boolean *kbl = &keyboard_look[forplayer]; boolean *kbl = &keyboard_look[forplayer];
boolean *rd = &resetdown[forplayer]; boolean *rd = &resetdown[forplayer];
const boolean mouseaiming = player->spectator; const boolean mouseaiming = player->spectator;
(void)realtics;
if (demo.playback) return; if (demo.playback) return;
// Is there any reason this can't just be I_BaseTiccmd? // Is there any reason this can't just be I_BaseTiccmd?
@ -953,39 +951,27 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
} }
forward = 0; forward = 0;
// use two stage accelerative turning
// on the keyboard and joystick
if (turnleft || turnright)
*th += realtics;
else
*th = 0;
if (*th < SLOWTURNTICS)
tspeed = 1; // slow turn
else
tspeed = 0;
cmd->turning = 0; cmd->turning = 0;
// let movement keys cancel each other out // let movement keys cancel each other out
if (turnright && !(turnleft)) if (turnright && !(turnleft))
{ {
cmd->turning = (INT16)(cmd->turning - (angleturn[tspeed])); cmd->turning -= KART_FULLTURN;
} }
else if (turnleft && !(turnright)) else if (turnleft && !(turnright))
{ {
cmd->turning = (INT16)(cmd->turning + (angleturn[tspeed])); cmd->turning += KART_FULLTURN;
} }
if (analogjoystickmove && joystickvector.xaxis != 0) if (analogjoystickmove && joystickvector.xaxis != 0)
{ {
cmd->turning = (INT16)(cmd->turning - (((joystickvector.xaxis * angleturn[0]) >> 10))); cmd->turning -= (joystickvector.xaxis * KART_FULLTURN) >> 10;
} }
// Specator mouse turning // Specator mouse turning
if (player->spectator) if (player->spectator)
{ {
cmd->turning = (INT16)(cmd->turning - ((mousex*(encoremode ? -1 : 1)*8))); cmd->turning -= (mousex * 8) * (encoremode ? -1 : 1);
} }
if (player->spectator || objectplacing) // SRB2Kart: spectators need special controls if (player->spectator || objectplacing) // SRB2Kart: spectators need special controls
@ -1050,6 +1036,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
if (PlayerInputDown(ssplayer, gc_drift) || (usejoystick && axis > 0)) if (PlayerInputDown(ssplayer, gc_drift) || (usejoystick && axis > 0))
cmd->buttons |= BT_DRIFT; cmd->buttons |= BT_DRIFT;
// Spindash with any button/key
// Simply holds all of the inputs for you.
axis = PlayerJoyAxis(ssplayer, AXISSPINDASH);
if (PlayerInputDown(ssplayer, gc_spindash) || (usejoystick && axis > 0))
cmd->buttons |= (BT_ACCELERATE|BT_BRAKE|BT_DRIFT);
// rear view with any button/key // rear view with any button/key
axis = PlayerJoyAxis(ssplayer, AXISLOOKBACK); axis = PlayerJoyAxis(ssplayer, AXISLOOKBACK);
if (PlayerInputDown(ssplayer, gc_lookback) || (usejoystick && axis > 0)) if (PlayerInputDown(ssplayer, gc_lookback) || (usejoystick && axis > 0))
@ -1120,7 +1112,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
cmd->forwardmove += (SINT8)forward; cmd->forwardmove += (SINT8)forward;
cmd->latency = modeattacking ? 0 : (leveltime & 0xFF); // Send leveltime when this tic was generated to the server for control lag calculations cmd->latency = (leveltime & 0xFF); // Send leveltime when this tic was generated to the server for control lag calculations
cmd->flags = 0; cmd->flags = 0;
if (chat_on || CON_Ready()) if (chat_on || CON_Ready())
@ -1153,10 +1145,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
else if (cmd->forwardmove < -MAXPLMOVE) else if (cmd->forwardmove < -MAXPLMOVE)
cmd->forwardmove = -MAXPLMOVE; cmd->forwardmove = -MAXPLMOVE;
if (cmd->turning > (angleturn[0])) if (cmd->turning > KART_FULLTURN)
cmd->turning = (angleturn[0]); cmd->turning = KART_FULLTURN;
else if (cmd->turning < (-angleturn[0])) else if (cmd->turning < -KART_FULLTURN)
cmd->turning = (-angleturn[0]); cmd->turning = -KART_FULLTURN;
// Reset away view if a command is given. // Reset away view if a command is given.
if ((cmd->forwardmove || cmd->buttons) if ((cmd->forwardmove || cmd->buttons)

View file

@ -106,6 +106,7 @@ typedef enum
AXISFIRE = AXISDIGITAL, AXISFIRE = AXISDIGITAL,
AXISDRIFT, AXISDRIFT,
AXISSPINDASH,
AXISLOOKBACK, AXISLOOKBACK,
AXISAIM, AXISAIM,
} axis_input_e; } axis_input_e;

View file

@ -52,11 +52,11 @@ const INT32 gcl_brake[num_gcl_brake] = { gc_brake };
const INT32 gcl_drift[num_gcl_drift] = { gc_drift }; const INT32 gcl_drift[num_gcl_drift] = { gc_drift };
const INT32 gcl_spindash[num_gcl_spindash] = { const INT32 gcl_spindash[num_gcl_spindash] = {
gc_accelerate, gc_drift, gc_brake gc_accelerate, gc_drift, gc_brake, gc_spindash
}; };
const INT32 gcl_movement[num_gcl_movement] = { const INT32 gcl_movement[num_gcl_movement] = {
gc_accelerate, gc_drift, gc_brake, gc_turnleft, gc_turnright gc_accelerate, gc_drift, gc_brake, gc_spindash, gc_turnleft, gc_turnright
}; };
const INT32 gcl_item[num_gcl_item] = { const INT32 gcl_item[num_gcl_item] = {
@ -64,7 +64,7 @@ const INT32 gcl_item[num_gcl_item] = {
}; };
const INT32 gcl_full[num_gcl_full] = { const INT32 gcl_full[num_gcl_full] = {
gc_accelerate, gc_drift, gc_brake, gc_turnleft, gc_turnright, gc_accelerate, gc_drift, gc_brake, gc_spindash, gc_turnleft, gc_turnright,
gc_fire, gc_aimforward, gc_aimbackward, gc_fire, gc_aimforward, gc_aimbackward,
gc_lookback gc_lookback
}; };

View file

@ -78,6 +78,7 @@ typedef enum
gc_accelerate, gc_accelerate,
gc_drift, gc_drift,
gc_brake, gc_brake,
gc_spindash,
gc_fire, gc_fire,
gc_lookback, gc_lookback,
gc_camreset, gc_camreset,
@ -129,10 +130,10 @@ extern INT32 gamecontroldefault[MAXSPLITSCREENPLAYERS][num_gamecontrolschemes][n
#define num_gcl_accelerate 1 #define num_gcl_accelerate 1
#define num_gcl_brake 1 #define num_gcl_brake 1
#define num_gcl_drift 1 #define num_gcl_drift 1
#define num_gcl_spindash 3 #define num_gcl_spindash 4
#define num_gcl_movement 5 #define num_gcl_movement 6
#define num_gcl_item 3 #define num_gcl_item 3
#define num_gcl_full 9 #define num_gcl_full 10
extern const INT32 gcl_accelerate[num_gcl_accelerate]; extern const INT32 gcl_accelerate[num_gcl_accelerate];
extern const INT32 gcl_brake[num_gcl_brake]; extern const INT32 gcl_brake[num_gcl_brake];

View file

@ -572,9 +572,11 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict
const fixed_t speed = max(P_AproxDistance(player->mo->momx, player->mo->momy), K_GetKartSpeed(player, false) / 4); const fixed_t speed = max(P_AproxDistance(player->mo->momx, player->mo->momy), K_GetKartSpeed(player, false) / 4);
const INT32 distance = (FixedMul(speed, distreduce) / FRACUNIT) * futuresight;
botprediction_t *predict = Z_Calloc(sizeof(botprediction_t), PU_LEVEL, NULL); const INT32 startDist = (768 * mapobjectscale) / FRACUNIT;
const INT32 distance = ((FixedMul(speed, distreduce) / FRACUNIT) * futuresight) + startDist;
botprediction_t *predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
waypoint_t *wp = player->nextwaypoint; waypoint_t *wp = player->nextwaypoint;
INT32 distanceleft = distance; INT32 distanceleft = distance;
@ -840,6 +842,70 @@ static INT16 K_FindBotController(mobj_t *mo)
return -1; return -1;
} }
/*--------------------------------------------------
static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
Draws objects to show where the viewpoint bot is trying to go.
Input Arguments:-
predict - The prediction to visualize.
player - The bot player this prediction is for.
Return:-
None
--------------------------------------------------*/
static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
{
mobj_t *debugMobj = NULL;
angle_t sideAngle = ANGLE_MAX;
UINT8 i = UINT8_MAX;
I_Assert(predict != NULL);
I_Assert(player != NULL);
I_Assert(player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
sideAngle = player->mo->angle + ANGLE_90;
debugMobj = P_SpawnMobj(predict->x, predict->y, player->mo->z, MT_SPARK);
P_SetMobjState(debugMobj, S_THOK);
debugMobj->frame &= ~FF_TRANSMASK;
debugMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
debugMobj->color = SKINCOLOR_ORANGE;
debugMobj->scale *= 2;
debugMobj->tics = 2;
for (i = 0; i < 2; i++)
{
mobj_t *radiusMobj = NULL;
fixed_t radiusX = predict->x, radiusY = predict->y;
if (i & 1)
{
radiusX -= FixedMul(predict->radius, FINECOSINE(sideAngle >> ANGLETOFINESHIFT));
radiusY -= FixedMul(predict->radius, FINESINE(sideAngle >> ANGLETOFINESHIFT));
}
else
{
radiusX += FixedMul(predict->radius, FINECOSINE(sideAngle >> ANGLETOFINESHIFT));
radiusY += FixedMul(predict->radius, FINESINE(sideAngle >> ANGLETOFINESHIFT));
}
radiusMobj = P_SpawnMobj(radiusX, radiusY, player->mo->z, MT_SPARK);
P_SetMobjState(radiusMobj, S_THOK);
radiusMobj->frame &= ~FF_TRANSMASK;
radiusMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
radiusMobj->color = SKINCOLOR_YELLOW;
radiusMobj->scale /= 2;
radiusMobj->tics = 2;
}
}
/*-------------------------------------------------- /*--------------------------------------------------
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
@ -866,6 +932,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
gamestate != GS_LEVEL gamestate != GS_LEVEL
|| player->mo->scale <= 1 || player->mo->scale <= 1
|| player->playerstate == PST_DEAD || player->playerstate == PST_DEAD
|| leveltime <= introtime
) )
{ {
// No need to do anything else. // No need to do anything else.
@ -930,7 +997,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
destangle = FixedAngle(sides[controllerLine->sidenum[0]].textureoffset); destangle = FixedAngle(sides[controllerLine->sidenum[0]].textureoffset);
// Overwritten prediction // Overwritten prediction
predict = Z_Calloc(sizeof(botprediction_t), PU_LEVEL, NULL); predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
predict->x = player->mo->x + FixedMul(dist, FINECOSINE(destangle >> ANGLETOFINESHIFT)); predict->x = player->mo->x + FixedMul(dist, FINECOSINE(destangle >> ANGLETOFINESHIFT));
predict->y = player->mo->y + FixedMul(dist, FINESINE(destangle >> ANGLETOFINESHIFT)); predict->y = player->mo->y + FixedMul(dist, FINESINE(destangle >> ANGLETOFINESHIFT));
@ -939,6 +1006,9 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
else else
{ {
predict = K_CreateBotPrediction(player); predict = K_CreateBotPrediction(player);
K_NudgePredictionTowardsObjects(predict, player);
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y); destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
} }
@ -1036,11 +1106,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
cmd->forwardmove /= 2; cmd->forwardmove /= 2;
cmd->buttons |= BT_BRAKE; cmd->buttons |= BT_BRAKE;
} }
else if (dirdist <= realrad)
{
// Steer towards/away from objects!
turnamt += K_BotFindObjects(player, turnamt);
}
} }
} }
@ -1056,7 +1121,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
finishBeamLine->v1->x, finishBeamLine->v1->y, finishBeamLine->v1->x, finishBeamLine->v1->y,
finishBeamLine->v2->x, finishBeamLine->v2->y, finishBeamLine->v2->x, finishBeamLine->v2->y,
player->mo->x, player->mo->y player->mo->x, player->mo->y
); ) - player->speed;
// Don't run the spindash code at all until we're in the right place // Don't run the spindash code at all until we're in the right place
trySpindash = false; trySpindash = false;
@ -1166,6 +1231,11 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
// Free the prediction we made earlier // Free the prediction we made earlier
if (predict != NULL) if (predict != NULL)
{ {
if (cv_kartdebugbotpredict.value != 0 && player - players == displayplayers[0])
{
K_DrawPredictionDebug(predict, player);
}
Z_Free(predict); Z_Free(predict);
} }
} }

View file

@ -198,19 +198,19 @@ fixed_t K_BotReducePrediction(player_t *player);
/*-------------------------------------------------- /*--------------------------------------------------
INT16 K_BotFindObjects(player_t *player, INT16 turn); void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player);
Generates a sum for objects to steer towards/away from. Moves the bot's prediction, based on objects around the bot.
Input Arguments:- Input Arguments:-
predict - The bot's prediction to nudge.
player - Player to compare. player - Player to compare.
turn - Turn value before object steering.
Return:- Return:-
Turn amount sum to add to final product. None
--------------------------------------------------*/ --------------------------------------------------*/
INT16 K_BotFindObjects(player_t *player, INT16 turn); void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player);
/*-------------------------------------------------- /*--------------------------------------------------

View file

@ -909,7 +909,7 @@ static void K_BotItemFlame(player_t *player, ticcmd_t *cmd)
--------------------------------------------------*/ --------------------------------------------------*/
static void K_BotItemRings(player_t *player, ticcmd_t *cmd) static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
{ {
INT32 saferingsval = 16 - K_GetKartRingPower(player); INT32 saferingsval = 16 - K_GetKartRingPower(player, false);
if (player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much if (player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much
|| player->kartstuff[k_speedboost] > (FRACUNIT/5)) // Have another type of boost (tethering) || player->kartstuff[k_speedboost] > (FRACUNIT/5)) // Have another type of boost (tethering)
@ -971,7 +971,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
{ {
// Use rings! // Use rings!
if (!player->exiting) if (leveltime > starttime && !player->exiting)
{ {
K_BotItemRings(player, cmd); K_BotItemRings(player, cmd);
} }

View file

@ -31,12 +31,16 @@
struct globalsmuggle struct globalsmuggle
{ {
mobj_t *botmo; mobj_t *botmo;
botprediction_t *predict;
fixed_t distancetocheck; fixed_t distancetocheck;
fixed_t closestlinedist; INT64 gotoAvgX[2], gotoAvgY[2];
UINT32 gotoObjs[2];
INT16 curturn; INT64 avoidAvgX[2], avoidAvgY[2];
INT16 steer; UINT32 avoidObjs[2];
fixed_t closestlinedist;
fixed_t eggboxx, eggboxy; fixed_t eggboxx, eggboxy;
UINT8 randomitems; UINT8 randomitems;
@ -383,7 +387,7 @@ fixed_t K_BotReducePrediction(player_t *player)
INT32 xl, xh, yl, yh, bx, by; INT32 xl, xh, yl, yh, bx, by;
globalsmuggle.botmo = player->mo; globalsmuggle.botmo = player->mo;
globalsmuggle.distancetocheck = (player->mo->radius * 16); globalsmuggle.distancetocheck = (player->mo->radius * 32);
globalsmuggle.closestlinedist = INT32_MAX; globalsmuggle.closestlinedist = INT32_MAX;
tmx = player->mo->x; tmx = player->mo->x;
@ -415,87 +419,107 @@ fixed_t K_BotReducePrediction(player_t *player)
return FRACUNIT; return FRACUNIT;
} }
return FixedDiv(globalsmuggle.closestlinedist, globalsmuggle.distancetocheck); return (FRACUNIT/2) + (FixedDiv(globalsmuggle.closestlinedist, globalsmuggle.distancetocheck) / 2);
} }
/*-------------------------------------------------- /*--------------------------------------------------
static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, fixed_t fulldist, fixed_t xdist, boolean towards, INT16 amount) static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
Handles steering away/towards the specified object. Adds an object to the list that the bot wants to go towards.
Input Arguments:- Input Arguments:-
bot - Bot's mobj. thing - Object to move towards.
thing - Mobj to steer towards/away from. side - Which side -- 0 for left, 1 for right
fulldist - Distance away from object. weight - How important this object is.
xdist - Horizontal distance away from object.
towards - If true, steer towards the object. Otherwise, steer away.
amount - How hard to turn.
Return:- Return:-
None None
--------------------------------------------------*/ --------------------------------------------------*/
static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, fixed_t fulldist, fixed_t xdist, boolean towards, INT16 amount) static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
{ {
angle_t destangle = R_PointToAngle2(bot->x, bot->y, thing->x, thing->y); UINT8 i;
angle_t angle;
SINT8 flip = 1;
amount = (amount * FixedDiv(globalsmuggle.distancetocheck - fulldist, globalsmuggle.distancetocheck)) / FRACUNIT; I_Assert(side <= 1);
if (amount == 0) if (weight == 0)
{ {
// Shouldn't happen
return; return;
} }
if (towards) for (i = 0; i < weight; i++)
{ {
if (xdist < FixedHypot(bot->radius, thing->radius)) globalsmuggle.gotoAvgX[side] += thing->x / mapobjectscale;
{ globalsmuggle.gotoAvgY[side] += thing->y / mapobjectscale;
// Don't need to turn any harder! globalsmuggle.gotoObjs[side]++;
if (abs(globalsmuggle.steer) <= amount)
{
globalsmuggle.steer = 0;
}
else
{
if (globalsmuggle.steer > 0)
{
globalsmuggle.steer -= amount;
}
else if (globalsmuggle.steer < 0)
{
globalsmuggle.steer += amount;
}
}
return;
}
// Still turning towards it, flip.
flip = -flip;
} }
angle = (bot->angle - destangle);
if (angle < ANGLE_180)
{
flip = -flip;
}
// If going in the opposite direction of where you wanted to turn,
// then reduce the amount that you can turn in that direction.
if ((flip == 1 && globalsmuggle.curturn < 0)
|| (flip == -1 && globalsmuggle.curturn > 0))
{
amount /= 4;
}
globalsmuggle.steer += amount * flip;
} }
/*-------------------------------------------------- /*--------------------------------------------------
static boolean K_BotSteerObjects(mobj_t *thing) static void K_AddDodgeObject(mobj_t *thing, UINT8 side, UINT8 weight)
Adds an object to the list that the bot wants to dodge.
Input Arguments:-
thing - Object to move away from.
side - Which side -- 0 for left, 1 for right
weight - How important this object is.
Return:-
None
--------------------------------------------------*/
static void K_AddDodgeObject(mobj_t *thing, UINT8 side, UINT8 weight)
{
UINT8 i;
I_Assert(side <= 1);
if (weight == 0)
{
return;
}
for (i = 0; i < weight; i++)
{
globalsmuggle.gotoAvgX[side] += thing->x / mapobjectscale;
globalsmuggle.gotoAvgY[side] += thing->y / mapobjectscale;
globalsmuggle.gotoObjs[side]++;
}
}
/*--------------------------------------------------
static boolean K_PlayerAttackSteer(mobj_t *thing, UINT8 side, UINT8 weight, boolean attackCond, boolean dodgeCond)
Checks two conditions to determine if the object should be
attacked or dodged.
Input Arguments:-
thing - Object to move towards/away from.
side - Which side -- 0 for left, 1 for right
weight - How important this object is.
attackCond - If this is true, and dodgeCond isn't, then we go towards the object.
dodgeCond - If this is true, and attackCond isn't, then we move away from the object.
Return:-
true if either condition is successful.
--------------------------------------------------*/
static boolean K_PlayerAttackSteer(mobj_t *thing, UINT8 side, UINT8 weight, boolean attackCond, boolean dodgeCond)
{
if (attackCond == true && dodgeCond == false)
{
K_AddAttackObject(thing, side, weight);
return true;
}
else if (dodgeCond == true && attackCond == false)
{
K_AddDodgeObject(thing, side, weight);
return true;
}
return false;
}
/*--------------------------------------------------
static boolean K_FindObjectsForNudging(mobj_t *thing)
Blockmap search function. Blockmap search function.
Finds objects around the bot to steer towards/away from. Finds objects around the bot to steer towards/away from.
@ -506,20 +530,19 @@ static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, fixed_t fulldist, fixe
Return:- Return:-
true continues searching, false ends the search early. true continues searching, false ends the search early.
--------------------------------------------------*/ --------------------------------------------------*/
static boolean K_BotSteerObjects(mobj_t *thing) static boolean K_FindObjectsForNudging(mobj_t *thing)
{ {
INT16 anglediff; INT16 anglediff;
fixed_t xdist, ydist, fulldist; fixed_t fulldist;
angle_t destangle, angle; angle_t destangle, angle, predictangle;
INT16 attack = ((9 - globalsmuggle.botmo->player->kartspeed) * KART_FULLTURN) / 8; // Acceleration chars are more aggressive UINT8 side = 0;
INT16 dodge = ((9 - globalsmuggle.botmo->player->kartweight) * KART_FULLTURN) / 8; // Handling chars dodge better
if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player) if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player)
{ {
return false; return false;
} }
if (!thing->health) if (thing->health <= 0)
{ {
return true; return true;
} }
@ -529,32 +552,21 @@ static boolean K_BotSteerObjects(mobj_t *thing)
return true; return true;
} }
xdist = K_DistanceOfLineFromPoint( fulldist = R_PointToDist2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y) - thing->radius;
globalsmuggle.botmo->x, globalsmuggle.botmo->y,
globalsmuggle.botmo->x + FINECOSINE(globalsmuggle.botmo->angle >> ANGLETOFINESHIFT), globalsmuggle.botmo->y + FINESINE(globalsmuggle.botmo->angle >> ANGLETOFINESHIFT),
thing->x, thing->y
) / 2; // weight x dist more heavily than y dist
ydist = K_DistanceOfLineFromPoint(
globalsmuggle.botmo->x, globalsmuggle.botmo->y,
globalsmuggle.botmo->x + FINECOSINE((globalsmuggle.botmo->angle + ANGLE_90) >> ANGLETOFINESHIFT), globalsmuggle.botmo->y + FINESINE((globalsmuggle.botmo->angle + ANGLE_90) >> ANGLETOFINESHIFT),
thing->x, thing->y
);
fulldist = FixedHypot(xdist, ydist);
if (fulldist > globalsmuggle.distancetocheck) if (fulldist > globalsmuggle.distancetocheck)
{ {
return true; return true;
} }
if (!P_CheckSight(globalsmuggle.botmo, thing)) if (P_CheckSight(globalsmuggle.botmo, thing) == false)
{ {
return true; return true;
} }
predictangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, globalsmuggle.predict->x, globalsmuggle.predict->y);
destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y); destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y);
angle = (globalsmuggle.botmo->angle - destangle); angle = (predictangle - destangle);
if (angle < ANGLE_180) if (angle < ANGLE_180)
{ {
@ -563,20 +575,11 @@ static boolean K_BotSteerObjects(mobj_t *thing)
else else
{ {
anglediff = 360-(AngleFixed(angle)>>FRACBITS); anglediff = 360-(AngleFixed(angle)>>FRACBITS);
side = 1;
} }
anglediff = abs(anglediff); anglediff = abs(anglediff);
#define PlayerAttackSteer(botcond, thingcond) \
if ((botcond) && !(thingcond)) \
{ \
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, 2 * (KART_FULLTURN + attack)); \
} \
else if ((thingcond) && !(botcond)) \
{ \
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge)); \
}
switch (thing->type) switch (thing->type)
{ {
case MT_BANANA: case MT_BANANA:
@ -593,21 +596,21 @@ static boolean K_BotSteerObjects(mobj_t *thing)
case MT_BALLHOG: case MT_BALLHOG:
case MT_SPB: case MT_SPB:
case MT_BUBBLESHIELDTRAP: case MT_BUBBLESHIELDTRAP:
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge)); K_AddDodgeObject(thing, side, 20);
break; break;
case MT_RANDOMITEM: case MT_RANDOMITEM:
if (anglediff >= 60) if (anglediff >= 45)
{ {
break; break;
} }
if (P_CanPickupItem(globalsmuggle.botmo->player, 1)) if (P_CanPickupItem(globalsmuggle.botmo->player, 1))
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, KART_FULLTURN + attack); K_AddAttackObject(thing, side, 10);
} }
break; break;
case MT_EGGMANITEM: case MT_EGGMANITEM:
if (anglediff >= 60) if (anglediff >= 45)
{ {
break; break;
} }
@ -619,28 +622,28 @@ static boolean K_BotSteerObjects(mobj_t *thing)
if (stealth >= requiredstealth) if (stealth >= requiredstealth)
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, 2 * (KART_FULLTURN + attack)); K_AddAttackObject(thing, side, 10);
} }
else else
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge)); K_AddDodgeObject(thing, side, 10);
} }
} }
break; break;
case MT_FLOATINGITEM: case MT_FLOATINGITEM:
if (anglediff >= 60) if (anglediff >= 45)
{ {
break; break;
} }
if (P_CanPickupItem(globalsmuggle.botmo->player, 3)) if (P_CanPickupItem(globalsmuggle.botmo->player, 3))
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, KART_FULLTURN + attack); K_AddAttackObject(thing, side, 20);
} }
break; break;
case MT_RING: case MT_RING:
case MT_FLINGRING: case MT_FLINGRING:
if (anglediff >= 60) if (anglediff >= 45)
{ {
break; break;
} }
@ -650,11 +653,7 @@ static boolean K_BotSteerObjects(mobj_t *thing)
&& !thing->extravalue1 && !thing->extravalue1
&& (globalsmuggle.botmo->player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD)) && (globalsmuggle.botmo->player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD))
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, K_AddAttackObject(thing, side, (RINGTOTAL(globalsmuggle.botmo->player) < 3) ? 5 : 1);
(RINGTOTAL(globalsmuggle.botmo->player) < 3
? (4 * (KART_FULLTURN + attack))
: (KART_FULLTURN + attack))
);
} }
break; break;
case MT_PLAYER: case MT_PLAYER:
@ -664,40 +663,61 @@ static boolean K_BotSteerObjects(mobj_t *thing)
{ {
// There REALLY ought to be a better way to handle this logic, right?! // There REALLY ought to be a better way to handle this logic, right?!
// Squishing // Squishing
PlayerAttackSteer( if (K_PlayerAttackSteer(thing, side, 20,
globalsmuggle.botmo->scale > thing->scale + (mapobjectscale/8), globalsmuggle.botmo->scale > thing->scale + (mapobjectscale/8),
thing->scale > globalsmuggle.botmo->scale + (mapobjectscale/8) thing->scale > globalsmuggle.botmo->scale + (mapobjectscale/8)
) ))
{
break;
}
// Invincibility // Invincibility
else PlayerAttackSteer( else if (K_PlayerAttackSteer(thing, side, 20,
globalsmuggle.botmo->player->kartstuff[k_invincibilitytimer], globalsmuggle.botmo->player->kartstuff[k_invincibilitytimer],
thing->player->kartstuff[k_invincibilitytimer] thing->player->kartstuff[k_invincibilitytimer]
) ))
{
break;
}
// Thunder Shield // Thunder Shield
else PlayerAttackSteer( else if (K_PlayerAttackSteer(thing, side, 20,
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD, globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD,
thing->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD thing->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD
) ))
{
break;
}
// Bubble Shield // Bubble Shield
else PlayerAttackSteer( else if (K_PlayerAttackSteer(thing, side, 20,
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD, globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD,
thing->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD thing->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD
) ))
{
break;
}
// Flame Shield // Flame Shield
else PlayerAttackSteer( else if (K_PlayerAttackSteer(thing, side, 20,
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD, globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD,
thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD
) ))
{
break;
}
// Has held item shield // Has held item shield
else PlayerAttackSteer( else if (K_PlayerAttackSteer(thing, side, 20,
(globalsmuggle.botmo->player->kartstuff[k_itemheld] || globalsmuggle.botmo->player->kartstuff[k_eggmanheld]), (globalsmuggle.botmo->player->kartstuff[k_itemheld] || globalsmuggle.botmo->player->kartstuff[k_eggmanheld]),
(thing->player->kartstuff[k_itemheld] || thing->player->kartstuff[k_eggmanheld]) (thing->player->kartstuff[k_itemheld] || thing->player->kartstuff[k_eggmanheld])
) ))
{
break;
}
// Ring Sting // Ring Sting
else PlayerAttackSteer( else if (K_PlayerAttackSteer(thing, side, 20,
thing->player->rings <= 0, thing->player->rings <= 0,
globalsmuggle.botmo->player->rings <= 0 globalsmuggle.botmo->player->rings <= 0
) ))
{
break;
}
else else
{ {
// After ALL of that, we can do standard bumping // After ALL of that, we can do standard bumping
@ -716,33 +736,43 @@ static boolean K_BotSteerObjects(mobj_t *thing)
if (weightdiff > mapobjectscale) if (weightdiff > mapobjectscale)
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, KART_FULLTURN + attack); K_AddAttackObject(thing, side, 20);
} }
else else
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, KART_FULLTURN + dodge); K_AddDodgeObject(thing, side, 20);
} }
} }
} }
break; break;
case MT_BOTHINT: case MT_BOTHINT:
if (anglediff >= 60) if (anglediff >= 45)
{ {
break; break;
} }
else
{
UINT8 weight = 20;
if (thing->extravalue1 == 0) if (thing->extravalue2 > 0)
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, thing->extravalue2 * (KART_FULLTURN + dodge)); weight = thing->extravalue2 * 5;
} }
{
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, thing->extravalue2 * (KART_FULLTURN + attack)); if (thing->extravalue1 == 0)
{
K_AddDodgeObject(thing, side, weight);
}
else
{
K_AddAttackObject(thing, side, weight);
}
} }
break; break;
default: default:
if (thing->flags & (MF_SOLID|MF_ENEMY|MF_BOSS|MF_PAIN|MF_MISSILE)) if (thing->flags & (MF_SOLID|MF_ENEMY|MF_BOSS|MF_PAIN|MF_MISSILE))
{ {
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge)); K_AddDodgeObject(thing, side, 20);
} }
break; break;
} }
@ -751,18 +781,40 @@ static boolean K_BotSteerObjects(mobj_t *thing)
} }
/*-------------------------------------------------- /*--------------------------------------------------
INT16 K_BotFindObjects(player_t *player, INT16 turn) void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
See header file for description. See header file for description.
--------------------------------------------------*/ --------------------------------------------------*/
INT16 K_BotFindObjects(player_t *player, INT16 turn) void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
{ {
INT32 xl, xh, yl, yh, bx, by; INT32 xl, xh, yl, yh, bx, by;
globalsmuggle.steer = 0; fixed_t distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
fixed_t avgX = 0, avgY = 0;
fixed_t avgDist = 0;
const fixed_t baseNudge = 128 * mapobjectscale;
fixed_t maxNudge = distToPredict;
fixed_t nudgeDist = 0;
angle_t nudgeDir = 0;
SINT8 gotoSide = -1;
UINT8 i;
globalsmuggle.botmo = player->mo; globalsmuggle.botmo = player->mo;
globalsmuggle.curturn = turn; globalsmuggle.predict = predict;
globalsmuggle.distancetocheck = (player->mo->radius * 32) + (player->speed * 4);
globalsmuggle.distancetocheck = distToPredict;
for (i = 0; i < 2; i++)
{
globalsmuggle.gotoAvgX[i] = globalsmuggle.gotoAvgY[i] = 0;
globalsmuggle.gotoObjs[i] = 0;
globalsmuggle.avoidAvgX[i] = globalsmuggle.avoidAvgY[i] = 0;
globalsmuggle.avoidObjs[i] = 0;
}
xl = (unsigned)(globalsmuggle.botmo->x - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT; xl = (unsigned)(globalsmuggle.botmo->x - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(globalsmuggle.botmo->x + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT; xh = (unsigned)(globalsmuggle.botmo->x + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
@ -775,9 +827,120 @@ INT16 K_BotFindObjects(player_t *player, INT16 turn)
{ {
for (by = yl; by <= yh; by++) for (by = yl; by <= yh; by++)
{ {
P_BlockThingsIterator(bx, by, K_BotSteerObjects); P_BlockThingsIterator(bx, by, K_FindObjectsForNudging);
} }
} }
return globalsmuggle.steer; // Handle dodge characters
if (globalsmuggle.avoidObjs[1] > 0 || globalsmuggle.avoidObjs[0] > 0)
{
if (globalsmuggle.avoidObjs[1] > globalsmuggle.avoidObjs[0])
{
gotoSide = 1;
}
else
{
gotoSide = 0;
}
avgX = (globalsmuggle.avoidAvgX[gotoSide] / globalsmuggle.avoidObjs[gotoSide]) * mapobjectscale;
avgY = (globalsmuggle.avoidAvgY[gotoSide] / globalsmuggle.avoidObjs[gotoSide]) * mapobjectscale;
avgDist = R_PointToDist2(
avgX, avgY,
predict->x, predict->y
);
// High handling characters dodge better
nudgeDist = ((9 - globalsmuggle.botmo->player->kartweight) + 1) * baseNudge;
maxNudge = max(distToPredict - predict->radius, predict->radius);
if (nudgeDist > maxNudge)
{
nudgeDist = maxNudge;
}
// Point away
nudgeDir = R_PointToAngle2(
avgX, avgY,
predict->x, predict->y
);
predict->x += FixedMul(nudgeDist, FINECOSINE(nudgeDir >> ANGLETOFINESHIFT));
predict->y += FixedMul(nudgeDist, FINESINE(nudgeDir >> ANGLETOFINESHIFT));
distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
// Flip side, since we want to check for objects to steer towards on the side we're NOT dodging.
if (gotoSide == 0)
{
gotoSide = 1;
}
else
{
gotoSide = 0;
}
}
if (gotoSide == -1)
{
// Pick a side here if there were no objects to dodge.
// We don't want to pick contradictory sides, so keep the old side otherwise,
// even if there's more to grab on the other side.
if (globalsmuggle.gotoObjs[1] > globalsmuggle.gotoObjs[0])
{
gotoSide = 1;
}
else
{
gotoSide = 0;
}
}
// Check if our side is invalid, if so, don't do the code below.
if (gotoSide != -1 && globalsmuggle.gotoObjs[gotoSide] == 0)
{
// Do not use a side
gotoSide = -1;
}
if (gotoSide != -1)
{
avgX = (globalsmuggle.gotoAvgX[gotoSide] / globalsmuggle.gotoObjs[gotoSide]) * mapobjectscale;
avgY = (globalsmuggle.gotoAvgY[gotoSide] / globalsmuggle.gotoObjs[gotoSide]) * mapobjectscale;
avgDist = R_PointToDist2(
predict->x, predict->y,
avgX, avgY
);
// Acceleration characters are more aggressive
nudgeDist = ((9 - globalsmuggle.botmo->player->kartspeed) + 1) * baseNudge;
maxNudge = max(distToPredict - predict->radius, predict->radius);
if (nudgeDist > maxNudge)
{
nudgeDist = maxNudge;
}
if (avgDist <= nudgeDist)
{
predict->x = avgX;
predict->y = avgY;
}
else
{
// Point towards
nudgeDir = R_PointToAngle2(
predict->x, predict->y,
avgX, avgY
);
predict->x += FixedMul(nudgeDist, FINECOSINE(nudgeDir >> ANGLETOFINESHIFT));
predict->y += FixedMul(nudgeDist, FINESINE(nudgeDir >> ANGLETOFINESHIFT));
//distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
}
}
} }

View file

@ -252,6 +252,7 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartdebugdistribution); CV_RegisterVar(&cv_kartdebugdistribution);
CV_RegisterVar(&cv_kartdebughuddrop); CV_RegisterVar(&cv_kartdebughuddrop);
CV_RegisterVar(&cv_kartdebugwaypoints); CV_RegisterVar(&cv_kartdebugwaypoints);
CV_RegisterVar(&cv_kartdebugbotpredict);
CV_RegisterVar(&cv_kartdebugcheckpoint); CV_RegisterVar(&cv_kartdebugcheckpoint);
CV_RegisterVar(&cv_kartdebugnodes); CV_RegisterVar(&cv_kartdebugnodes);
@ -6935,11 +6936,11 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
} }
} }
INT32 K_GetKartRingPower(player_t *player) INT32 K_GetKartRingPower(player_t *player, boolean boosted)
{ {
INT32 ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) / 2; INT32 ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) / 2;
if (K_PlayerUsesBotMovement(player)) if (boosted == true && K_PlayerUsesBotMovement(player))
{ {
// Double for Lv. 9 // Double for Lv. 9
ringPower += (player->botvars.difficulty * ringPower) / MAXBOTDIFFICULTY; ringPower += (player->botvars.difficulty * ringPower) / MAXBOTDIFFICULTY;

View file

@ -69,7 +69,7 @@ void K_UpdateHnextList(player_t *player, boolean clean);
void K_DropHnextList(player_t *player, boolean keepshields); void K_DropHnextList(player_t *player, boolean keepshields);
void K_RepairOrbitChain(mobj_t *orbit); void K_RepairOrbitChain(mobj_t *orbit);
player_t *K_FindJawzTarget(mobj_t *actor, player_t *source); player_t *K_FindJawzTarget(mobj_t *actor, player_t *source);
INT32 K_GetKartRingPower(player_t *player); INT32 K_GetKartRingPower(player_t *player, boolean boosted);
void K_UpdateDistanceFromFinishLine(player_t *const player); void K_UpdateDistanceFromFinishLine(player_t *const player);
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);

View file

@ -535,9 +535,9 @@ static void K_DebugWaypointsSpawnLine(waypoint_t *const waypoint1, waypoint_t *c
{ {
spawnedmobj = P_SpawnMobj(x, y, z, MT_SPARK); spawnedmobj = P_SpawnMobj(x, y, z, MT_SPARK);
P_SetMobjState(spawnedmobj, S_THOK); P_SetMobjState(spawnedmobj, S_THOK);
spawnedmobj->state->nextstate = S_NULL; spawnedmobj->tics = 1;
spawnedmobj->state->tics = 1; spawnedmobj->frame &= ~FF_TRANSMASK;
spawnedmobj->frame = spawnedmobj->frame & ~FF_TRANSMASK; spawnedmobj->frame |= FF_FULLBRIGHT;
spawnedmobj->color = linkcolour; spawnedmobj->color = linkcolour;
spawnedmobj->scale = FixedMul(spawnedmobj->scale, FixedMul(FRACUNIT/4, FixedDiv((15 - ((leveltime + n) % 16))*FRACUNIT, 15*FRACUNIT))); spawnedmobj->scale = FixedMul(spawnedmobj->scale, FixedMul(FRACUNIT/4, FixedDiv((15 - ((leveltime + n) % 16))*FRACUNIT, 15*FRACUNIT)));
} }
@ -582,9 +582,9 @@ static void K_DebugWaypointDrawRadius(waypoint_t *const waypoint)
radiusOrb = P_SpawnMobj(spawnX, spawnY, spawnZ, MT_SPARK); radiusOrb = P_SpawnMobj(spawnX, spawnY, spawnZ, MT_SPARK);
P_SetMobjState(radiusOrb, S_THOK); P_SetMobjState(radiusOrb, S_THOK);
radiusOrb->state->nextstate = S_NULL; radiusOrb->tics = 1;
radiusOrb->state->tics = 1; radiusOrb->frame &= ~FF_TRANSMASK;
radiusOrb->frame = radiusOrb->frame & ~FF_TRANSMASK; radiusOrb->frame |= FF_FULLBRIGHT;
radiusOrb->color = SKINCOLOR_PURPLE; radiusOrb->color = SKINCOLOR_PURPLE;
radiusOrb->scale = radiusOrb->scale / 4; radiusOrb->scale = radiusOrb->scale / 4;
} }
@ -623,7 +623,7 @@ void K_DebugWaypointsVisualise(void)
P_SetMobjState(debugmobj, S_THOK); P_SetMobjState(debugmobj, S_THOK);
debugmobj->frame &= ~FF_TRANSMASK; debugmobj->frame &= ~FF_TRANSMASK;
debugmobj->frame |= FF_TRANS20; debugmobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
// There's a waypoint setup for this mobj! So draw that it's a valid waypoint and draw lines to its connections // There's a waypoint setup for this mobj! So draw that it's a valid waypoint and draw lines to its connections
if (waypoint != NULL) if (waypoint != NULL)
@ -683,8 +683,7 @@ void K_DebugWaypointsVisualise(void)
{ {
debugmobj->color = SKINCOLOR_RED; debugmobj->color = SKINCOLOR_RED;
} }
debugmobj->state->tics = 1; debugmobj->tics = 1;
debugmobj->state->nextstate = S_NULL;
} }
} }

View file

@ -1142,6 +1142,7 @@ static menuitem_t OP_AllControlsMenu[] =
{IT_CONTROL, NULL, "Turn Right", M_ChangeControl, gc_turnright }, {IT_CONTROL, NULL, "Turn Right", M_ChangeControl, gc_turnright },
{IT_CONTROL, NULL, "Drift", M_ChangeControl, gc_drift }, {IT_CONTROL, NULL, "Drift", M_ChangeControl, gc_drift },
{IT_CONTROL, NULL, "Brake", M_ChangeControl, gc_brake }, {IT_CONTROL, NULL, "Brake", M_ChangeControl, gc_brake },
{IT_CONTROL, NULL, "Spindash", M_ChangeControl, gc_spindash },
{IT_CONTROL, NULL, "Use/Throw Item", M_ChangeControl, gc_fire }, {IT_CONTROL, NULL, "Use/Throw Item", M_ChangeControl, gc_fire },
{IT_CONTROL, NULL, "Aim Forward", M_ChangeControl, gc_aimforward }, {IT_CONTROL, NULL, "Aim Forward", M_ChangeControl, gc_aimforward },
{IT_CONTROL, NULL, "Aim Backward", M_ChangeControl, gc_aimbackward}, {IT_CONTROL, NULL, "Aim Backward", M_ChangeControl, gc_aimbackward},
@ -2703,8 +2704,8 @@ boolean M_Responder(event_t *ev)
M_QuitSRB2(0); M_QuitSRB2(0);
return true; return true;
case KEY_F11: // Gamma Level case KEY_F11: // Fullscreen
CV_AddValue(&cv_globalgamma, 1); CV_AddValue(&cv_fullscreen, 1);
return true; return true;
// Spymode on F12 handled in game logic // Spymode on F12 handled in game logic
@ -6146,7 +6147,6 @@ static void M_PlaybackToggleFreecam(INT32 choice)
demo.freecam = false; demo.freecam = false;
// reset democam vars: // reset democam vars:
democam.cam = NULL; democam.cam = NULL;
democam.turnheld = false;
democam.keyboardlook = false; // reset only these. localangle / aiming gets set before the cam does anything anyway democam.keyboardlook = false; // reset only these. localangle / aiming gets set before the cam does anything anyway
} }
} }
@ -10404,22 +10404,22 @@ static void M_Setup1PControlsMenu(INT32 choice)
OP_AllControlsMenu[0].itemaction = &OP_Joystick1Def; OP_AllControlsMenu[0].itemaction = &OP_Joystick1Def;
// Unhide P1-only controls // Unhide P1-only controls
OP_AllControlsMenu[15].status = IT_CONTROL; // Chat OP_AllControlsMenu[16].status = IT_CONTROL; // Chat
//OP_AllControlsMenu[16].status = IT_CONTROL; // Team-chat //OP_AllControlsMenu[17].status = IT_CONTROL; // Team-chat
OP_AllControlsMenu[16].status = IT_CONTROL; // Rankings OP_AllControlsMenu[17].status = IT_CONTROL; // Rankings
//OP_AllControlsMenu[17].status = IT_CONTROL; // Viewpoint //OP_AllControlsMenu[18].status = IT_CONTROL; // Viewpoint
// 18 is Reset Camera, 19 is Toggle Chasecam // 19 is Reset Camera, 20 is Toggle Chasecam
OP_AllControlsMenu[20].status = IT_CONTROL; // Pause OP_AllControlsMenu[21].status = IT_CONTROL; // Pause
OP_AllControlsMenu[21].status = IT_CONTROL; // Screenshot OP_AllControlsMenu[22].status = IT_CONTROL; // Screenshot
OP_AllControlsMenu[22].status = IT_CONTROL; // GIF OP_AllControlsMenu[23].status = IT_CONTROL; // GIF
OP_AllControlsMenu[23].status = IT_CONTROL; // System Menu OP_AllControlsMenu[24].status = IT_CONTROL; // System Menu
OP_AllControlsMenu[24].status = IT_CONTROL; // Console OP_AllControlsMenu[25].status = IT_CONTROL; // Console
/*OP_AllControlsMenu[25].status = IT_HEADER; // Spectator Controls header /*OP_AllControlsMenu[26].status = IT_HEADER; // Spectator Controls header
OP_AllControlsMenu[26].status = IT_SPACE; // Spectator Controls space OP_AllControlsMenu[27].status = IT_SPACE; // Spectator Controls space
OP_AllControlsMenu[27].status = IT_CONTROL; // Spectate OP_AllControlsMenu[28].status = IT_CONTROL; // Spectate
OP_AllControlsMenu[28].status = IT_CONTROL; // Look Up OP_AllControlsMenu[29].status = IT_CONTROL; // Look Up
OP_AllControlsMenu[29].status = IT_CONTROL; // Look Down OP_AllControlsMenu[30].status = IT_CONTROL; // Look Down
OP_AllControlsMenu[30].status = IT_CONTROL; // Center View OP_AllControlsMenu[31].status = IT_CONTROL; // Center View
*/ */
M_SetupNextMenu(&OP_AllControlsDef); M_SetupNextMenu(&OP_AllControlsDef);
@ -10436,22 +10436,22 @@ static void M_Setup2PControlsMenu(INT32 choice)
OP_AllControlsMenu[0].itemaction = &OP_Joystick2Def; OP_AllControlsMenu[0].itemaction = &OP_Joystick2Def;
// Hide P1-only controls // Hide P1-only controls
OP_AllControlsMenu[15].status = IT_GRAYEDOUT2; // Chat OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Chat
//OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Team-chat //OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Team-chat
OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Rankings OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Rankings
//OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Viewpoint //OP_AllControlsMenu[18].status = IT_GRAYEDOUT2; // Viewpoint
// 18 is Reset Camera, 19 is Toggle Chasecam // 19 is Reset Camera, 20 is Toggle Chasecam
OP_AllControlsMenu[20].status = IT_GRAYEDOUT2; // Pause OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Pause
OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Screenshot OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // Screenshot
OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // GIF OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // GIF
OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // System Menu OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // System Menu
OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // Console OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Console
/*OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Spectator Controls header /*OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls header
OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls space OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectator Controls space
OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectate OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Spectate
OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Look Up OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Up
OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Down OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Look Down
OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Center View OP_AllControlsMenu[31].status = IT_GRAYEDOUT2; // Center View
*/ */
M_SetupNextMenu(&OP_AllControlsDef); M_SetupNextMenu(&OP_AllControlsDef);
@ -10468,22 +10468,22 @@ static void M_Setup3PControlsMenu(INT32 choice)
OP_AllControlsMenu[0].itemaction = &OP_Joystick3Def; OP_AllControlsMenu[0].itemaction = &OP_Joystick3Def;
// Hide P1-only controls // Hide P1-only controls
OP_AllControlsMenu[15].status = IT_GRAYEDOUT2; // Chat OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Chat
//OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Team-chat //OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Team-chat
OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Rankings OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Rankings
//OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Viewpoint //OP_AllControlsMenu[18].status = IT_GRAYEDOUT2; // Viewpoint
// 18 is Reset Camera, 19 is Toggle Chasecam // 19 is Reset Camera, 20 is Toggle Chasecam
OP_AllControlsMenu[20].status = IT_GRAYEDOUT2; // Pause OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Pause
OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Screenshot OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // Screenshot
OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // GIF OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // GIF
OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // System Menu OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // System Menu
OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // Console OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Console
/*OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Spectator Controls header /*OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls header
OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls space OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectator Controls space
OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectate OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Spectate
OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Look Up OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Up
OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Down OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Look Down
OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Center View OP_AllControlsMenu[31].status = IT_GRAYEDOUT2; // Center View
*/ */
M_SetupNextMenu(&OP_AllControlsDef); M_SetupNextMenu(&OP_AllControlsDef);
@ -10500,22 +10500,22 @@ static void M_Setup4PControlsMenu(INT32 choice)
OP_AllControlsMenu[0].itemaction = &OP_Joystick4Def; OP_AllControlsMenu[0].itemaction = &OP_Joystick4Def;
// Hide P1-only controls // Hide P1-only controls
OP_AllControlsMenu[15].status = IT_GRAYEDOUT2; // Chat OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Chat
//OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Team-chat //OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Team-chat
OP_AllControlsMenu[16].status = IT_GRAYEDOUT2; // Rankings OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Rankings
//OP_AllControlsMenu[17].status = IT_GRAYEDOUT2; // Viewpoint //OP_AllControlsMenu[18].status = IT_GRAYEDOUT2; // Viewpoint
// 18 is Reset Camera, 19 is Toggle Chasecam // 19 is Reset Camera, 20 is Toggle Chasecam
OP_AllControlsMenu[20].status = IT_GRAYEDOUT2; // Pause OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Pause
OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Screenshot OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // Screenshot
OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // GIF OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // GIF
OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // System Menu OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // System Menu
OP_AllControlsMenu[24].status = IT_GRAYEDOUT2; // Console OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Console
/*OP_AllControlsMenu[25].status = IT_GRAYEDOUT2; // Spectator Controls header /*OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls header
OP_AllControlsMenu[26].status = IT_GRAYEDOUT2; // Spectator Controls space OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectator Controls space
OP_AllControlsMenu[27].status = IT_GRAYEDOUT2; // Spectate OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Spectate
OP_AllControlsMenu[28].status = IT_GRAYEDOUT2; // Look Up OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Up
OP_AllControlsMenu[29].status = IT_GRAYEDOUT2; // Look Down OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Look Down
OP_AllControlsMenu[30].status = IT_GRAYEDOUT2; // Center View OP_AllControlsMenu[31].status = IT_GRAYEDOUT2; // Center View
*/ */
M_SetupNextMenu(&OP_AllControlsDef); M_SetupNextMenu(&OP_AllControlsDef);

View file

@ -4172,7 +4172,7 @@ void A_AttractChase(mobj_t *actor)
angle_t offset = FixedAngle(18<<FRACBITS); angle_t offset = FixedAngle(18<<FRACBITS);
// Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end // Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player)+3; actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player, true) + 3;
S_StartSound(actor->target, sfx_s1b5); S_StartSound(actor->target, sfx_s1b5);
sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS); sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS);
@ -4200,7 +4200,7 @@ void A_AttractChase(mobj_t *actor)
if (actor->extravalue1 >= 16) if (actor->extravalue1 >= 16)
{ {
if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player)+3; actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player, true) + 3;
if (actor->cvmem) // caching if (actor->cvmem) // caching
S_StartSound(actor->target, sfx_s1c5); S_StartSound(actor->target, sfx_s1c5);

View file

@ -1863,7 +1863,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!(target->flags & MF_SHOOTABLE)) if (!(target->flags & MF_SHOOTABLE))
return false; // shouldn't happen... return false; // shouldn't happen...
if (target->hitlag > 0) if (!(damagetype & DMG_DEATHMASK) && target->hitlag > 0)
return false; return false;
} }
@ -1947,7 +1947,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (combo == false) if (combo == false)
{ {
if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinouttype] != 2)) if (player->powers[pw_flashing] > 0)
{ {
// Post-hit invincibility // Post-hit invincibility
K_DoInstashield(player); K_DoInstashield(player);

View file

@ -11803,7 +11803,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
// Steering amount // Steering amount
if (mthing->args[1] == 0) if (mthing->args[1] == 0)
{ {
mobj->extravalue2 = 2; mobj->extravalue2 = 4;
} }
else else
{ {

View file

@ -1699,7 +1699,7 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
else if (fastcmp(param, "type")) else if (fastcmp(param, "type"))
mapthings[i].type = atol(val); mapthings[i].type = atol(val);
else if (fastcmp(param, "scale") || fastcmp(param, "scalex") || fastcmp(param, "scaley")) else if (fastcmp(param, "scale") || fastcmp(param, "scalex") || fastcmp(param, "scaley"))
mapthings[i].scale = FLOAT_TO_FIXED(atof(val)); mapthings[i].scale = FixedMul(mapobjectscale, FLOAT_TO_FIXED(atof(val)));
// Flags // Flags
else if (fastcmp(param, "extra") && fastcmp("true", val)) else if (fastcmp(param, "extra") && fastcmp("true", val))
mapthings[i].options |= MTF_EXTRA; mapthings[i].options |= MTF_EXTRA;

View file

@ -2776,9 +2776,7 @@ fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
// Heavily simplified version of G_BuildTicCmd that only takes the local first player's control input and converts it to readable ticcmd_t // Heavily simplified version of G_BuildTicCmd that only takes the local first player's control input and converts it to readable ticcmd_t
// we then throw that ticcmd garbage in the camera and make it move // we then throw that ticcmd garbage in the camera and make it move
// TODO: please just use the normal ticcmd function somehow
// redefine this
static fixed_t angleturn[2] = {KART_FULLTURN, KART_FULLTURN/4}; // + slow turn
static ticcmd_t cameracmd; static ticcmd_t cameracmd;
@ -2792,7 +2790,7 @@ void P_InitCameraCmd(void)
static ticcmd_t *P_CameraCmd(camera_t *cam) static ticcmd_t *P_CameraCmd(camera_t *cam)
{ {
INT32 th, tspeed, forward, axis; //i INT32 forward, axis; //i
// these ones used for multiple conditions // these ones used for multiple conditions
boolean turnleft, turnright, mouseaiming; boolean turnleft, turnright, mouseaiming;
boolean invertmouse, lookaxis, usejoystick, kbl; boolean invertmouse, lookaxis, usejoystick, kbl;
@ -2805,7 +2803,6 @@ static ticcmd_t *P_CameraCmd(camera_t *cam)
if (!demo.playback) if (!demo.playback)
return cmd; // empty cmd, no. return cmd; // empty cmd, no.
th = democam.turnheld;
kbl = democam.keyboardlook; kbl = democam.keyboardlook;
G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver
@ -2835,31 +2832,19 @@ static ticcmd_t *P_CameraCmd(camera_t *cam)
} }
forward = 0; forward = 0;
// use two stage accelerative turning
// on the keyboard and joystick
if (turnleft || turnright)
th += 1;
else
th = 0;
if (th < SLOWTURNTICS)
tspeed = 1; // slow turn
else
tspeed = 0;
cmd->turning = 0; cmd->turning = 0;
// let movement keys cancel each other out // let movement keys cancel each other out
if (turnright && !(turnleft)) if (turnright && !(turnleft))
{ {
cmd->turning = (INT16)(cmd->turning - (angleturn[tspeed])); cmd->turning -= KART_FULLTURN;
} }
else if (turnleft && !(turnright)) else if (turnleft && !(turnright))
{ {
cmd->turning = (INT16)(cmd->turning + (angleturn[tspeed])); cmd->turning += KART_FULLTURN;
} }
cmd->turning = (INT16)(cmd->turning - ((mousex*(encoremode ? -1 : 1)*8))); cmd->turning -= (mousex * 8) * (encoremode ? -1 : 1);
axis = PlayerJoyAxis(1, AXISMOVE); axis = PlayerJoyAxis(1, AXISMOVE);
if (PlayerInputDown(1, gc_accelerate) || (usejoystick && axis > 0)) if (PlayerInputDown(1, gc_accelerate) || (usejoystick && axis > 0))
@ -2917,7 +2902,11 @@ static ticcmd_t *P_CameraCmd(camera_t *cam)
else if (cmd->forwardmove < -MAXPLMOVE) else if (cmd->forwardmove < -MAXPLMOVE)
cmd->forwardmove = -MAXPLMOVE; cmd->forwardmove = -MAXPLMOVE;
democam.turnheld = th; if (cmd->turning > KART_FULLTURN)
cmd->turning = KART_FULLTURN;
else if (cmd->turning < -KART_FULLTURN)
cmd->turning = -KART_FULLTURN;
democam.keyboardlook = kbl; democam.keyboardlook = kbl;
return cmd; return cmd;