Merge branch 'master' into bots-brake-earlier
This commit is contained in:
commit
a4b673705a
46 changed files with 998 additions and 345 deletions
|
|
@ -233,7 +233,10 @@ void D_ProcessEvents(void)
|
|||
#endif
|
||||
|
||||
if (eaten)
|
||||
{
|
||||
hu_keystrokes = true;
|
||||
continue; // ate the event
|
||||
}
|
||||
|
||||
G_Responder(ev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -939,6 +939,7 @@ void D_RegisterClientCommands(void)
|
|||
// g_input.c
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
CV_RegisterVar(&cv_kickstartaccel[i]);
|
||||
CV_RegisterVar(&cv_turnaxis[i]);
|
||||
CV_RegisterVar(&cv_moveaxis[i]);
|
||||
CV_RegisterVar(&cv_brakeaxis[i]);
|
||||
|
|
@ -1627,6 +1628,8 @@ void SendWeaponPref(UINT8 n)
|
|||
|
||||
buf[0] = 0;
|
||||
// Player option cvars that need to be synched go HERE
|
||||
if (cv_kickstartaccel[n].value)
|
||||
buf[0] |= 1;
|
||||
|
||||
SendNetXCmdForPlayer(n, XD_WEAPONPREF, buf, 1);
|
||||
}
|
||||
|
|
@ -1635,11 +1638,13 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
|
|||
{
|
||||
UINT8 prefs = READUINT8(*cp);
|
||||
|
||||
(void)prefs;
|
||||
(void)playernum;
|
||||
|
||||
//players[playernum].pflags &= ~(PF_FLIPCAM);
|
||||
// Player option cvars that need to be synched go HERE
|
||||
players[playernum].pflags &= ~(PF_KICKSTARTACCEL);
|
||||
if (prefs & 1)
|
||||
players[playernum].pflags |= PF_KICKSTARTACCEL;
|
||||
|
||||
// SEE ALSO g_demo.c
|
||||
demo_extradata[playernum] |= DXD_WEAPONPREF;
|
||||
}
|
||||
|
||||
static void Got_PowerLevel(UINT8 **cp,INT32 playernum)
|
||||
|
|
@ -3374,9 +3379,11 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
if (players[playernum].mo)
|
||||
{
|
||||
P_DamageMobj(players[playernum].mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||
P_DamageMobj(players[playernum].mo, NULL, NULL, 1,
|
||||
(NetPacket.packet.newteam ? DMG_INSTAKILL : DMG_SPECTATOR));
|
||||
}
|
||||
else
|
||||
//else
|
||||
if (!NetPacket.packet.newteam)
|
||||
{
|
||||
players[playernum].playerstate = PST_REBORN;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,48 +67,45 @@ typedef enum
|
|||
|
||||
// True if button down last tic.
|
||||
PF_ATTACKDOWN = 1<<7,
|
||||
PF_SPINDOWN = 1<<8,
|
||||
PF_JUMPDOWN = 1<<9,
|
||||
PF_WPNDOWN = 1<<10,
|
||||
PF_ACCELDOWN = 1<<8,
|
||||
PF_BRAKEDOWN = 1<<9,
|
||||
PF_WPNDOWN = 1<<10, // unused
|
||||
|
||||
// Unmoving states
|
||||
PF_STASIS = 1<<11, // Player is not allowed to move
|
||||
PF_JUMPSTASIS = 1<<12, // and that includes jumping.
|
||||
PF_FULLSTASIS = PF_STASIS|PF_JUMPSTASIS,
|
||||
PF_JUMPSTASIS = 1<<12, // unused
|
||||
|
||||
// SRB2Kart: Spectator that wants to join
|
||||
PF_WANTSTOJOIN = 1<<13,
|
||||
|
||||
// Character action status
|
||||
PF_STARTJUMP = 1<<14,
|
||||
PF_JUMPED = 1<<15,
|
||||
PF_NOJUMPDAMAGE = 1<<16,
|
||||
|
||||
PF_SPINNING = 1<<17,
|
||||
PF_STARTDASH = 1<<18,
|
||||
|
||||
PF_THOKKED = 1<<19,
|
||||
PF_SHIELDABILITY = 1<<20,
|
||||
PF_GLIDING = 1<<21,
|
||||
PF_BOUNCING = 1<<22,
|
||||
PF_STARTJUMP = 1<<14, // unused
|
||||
PF_JUMPED = 1<<15, // unused
|
||||
PF_NOJUMPDAMAGE = 1<<16, // unused
|
||||
PF_SPINNING = 1<<17, // unused
|
||||
PF_STARTDASH = 1<<18, // unused
|
||||
PF_THOKKED = 1<<19, // unused
|
||||
PF_SHIELDABILITY = 1<<20, // unused
|
||||
PF_GLIDING = 1<<21, // unused
|
||||
PF_BOUNCING = 1<<22, // unused
|
||||
|
||||
// Sliding (usually in water) like Labyrinth/Oil Ocean
|
||||
PF_SLIDING = 1<<23,
|
||||
|
||||
// NiGHTS stuff
|
||||
PF_TRANSFERTOCLOSEST = 1<<24,
|
||||
PF_DRILLING = 1<<25,
|
||||
PF_TRANSFERTOCLOSEST = 1<<24, // unused
|
||||
PF_DRILLING = 1<<25, // unused
|
||||
|
||||
// Gametype-specific stuff
|
||||
PF_GAMETYPEOVER = 1<<26, // Race time over, or H&S out-of-game
|
||||
PF_TAGIT = 1<<27, // The player is it! For Tag Mode
|
||||
PF_GAMETYPEOVER = 1<<26, // Race time over
|
||||
PF_TAGIT = 1<<27, // unused
|
||||
|
||||
/*** misc ***/
|
||||
PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs
|
||||
PF_CANCARRY = 1<<29, // Can carry another player?
|
||||
PF_KICKSTARTACCEL = 1<<28, // Accessibility feature - is accelerate in kickstart mode?
|
||||
PF_CANCARRY = 1<<29, // unused
|
||||
PF_HITFINISHLINE = 1<<30, // Already hit the finish line this tic
|
||||
|
||||
// up to 1<<31 is free
|
||||
// up to 1<<31 is free, but try to hit unused stuff first
|
||||
} pflags_t;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -450,6 +447,9 @@ typedef enum
|
|||
|
||||
//}
|
||||
|
||||
// for kickstartaccel
|
||||
#define ACCEL_KICKSTART 35
|
||||
|
||||
// player_t struct for all respawn variables
|
||||
typedef struct respawnvars_s
|
||||
{
|
||||
|
|
@ -697,6 +697,11 @@ typedef struct player_s
|
|||
tic_t jointime; // Timer when player joins game to change skin/color
|
||||
tic_t quittime; // Time elapsed since user disconnected, zero if connected
|
||||
|
||||
UINT8 typing_timer; // Counts down while keystrokes are not emitted
|
||||
UINT8 typing_duration; // How long since resumed timer
|
||||
|
||||
UINT8 kickstartaccel;
|
||||
|
||||
#ifdef HWRENDER
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,17 +26,17 @@
|
|||
// Button/action code definitions.
|
||||
typedef enum
|
||||
{
|
||||
BT_ACCELERATE = 1, // Accelerate
|
||||
BT_DRIFT = 1<<2, // Drift (direction is cmd->turning)
|
||||
BT_BRAKE = 1<<3, // Brake
|
||||
BT_ATTACK = 1<<4, // Use Item
|
||||
BT_FORWARD = 1<<5, // Aim Item Forward
|
||||
BT_BACKWARD = 1<<6, // Aim Item Backward
|
||||
BT_LOOKBACK = 1<<7, // Look Backward
|
||||
BT_ACCELERATE = 1, // Accelerate
|
||||
BT_DRIFT = 1<<2, // Drift (direction is cmd->turning)
|
||||
BT_BRAKE = 1<<3, // Brake
|
||||
BT_ATTACK = 1<<4, // Use Item
|
||||
BT_FORWARD = 1<<5, // Aim Item Forward
|
||||
BT_BACKWARD = 1<<6, // Aim Item Backward
|
||||
BT_LOOKBACK = 1<<7, // Look Backward
|
||||
|
||||
BT_EBRAKEMASK = (BT_ACCELERATE|BT_BRAKE),
|
||||
|
||||
// free: 1<<8 to 1<<12
|
||||
// free: 1<<9 to 1<<12
|
||||
|
||||
// Lua garbage
|
||||
BT_CUSTOM1 = 1<<13,
|
||||
|
|
@ -54,6 +54,8 @@ typedef enum
|
|||
|
||||
// ticcmd flags
|
||||
#define TICCMD_RECEIVED 1
|
||||
#define TICCMD_TYPING 2/* chat window or console open */
|
||||
#define TICCMD_KEYSTROKE 4/* chat character input */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
|
|
|
|||
|
|
@ -10645,17 +10645,13 @@ static const char *const PLAYERFLAG_LIST[] = {
|
|||
|
||||
// True if button down last tic.
|
||||
"ATTACKDOWN",
|
||||
"SPINDOWN",
|
||||
"JUMPDOWN",
|
||||
"ACCELDOWN",
|
||||
"BRAKEDOWN",
|
||||
"WPNDOWN",
|
||||
|
||||
// Unmoving states
|
||||
"STASIS", // Player is not allowed to move
|
||||
"JUMPSTASIS", // and that includes jumping.
|
||||
// (we don't include FULLSTASIS here I guess because it's just those two together...?)
|
||||
|
||||
// Did you get a time-over?
|
||||
"TIMEOVER",
|
||||
|
||||
// SRB2Kart: spectator that wants to join
|
||||
"WANTSTOJOIN",
|
||||
|
|
@ -10664,10 +10660,8 @@ static const char *const PLAYERFLAG_LIST[] = {
|
|||
"STARTJUMP",
|
||||
"JUMPED",
|
||||
"NOJUMPDAMAGE",
|
||||
|
||||
"SPINNING",
|
||||
"STARTDASH",
|
||||
|
||||
"THOKKED",
|
||||
"SHIELDABILITY",
|
||||
"GLIDING",
|
||||
|
|
@ -10681,13 +10675,13 @@ static const char *const PLAYERFLAG_LIST[] = {
|
|||
"DRILLING",
|
||||
|
||||
// Gametype-specific stuff
|
||||
"GAMETYPEOVER", // Race time over, or H&S out-of-game
|
||||
"TAGIT", // The player is it! For Tag Mode
|
||||
"GAMETYPEOVER", // Race time over
|
||||
"TAGIT",
|
||||
|
||||
/*** misc ***/
|
||||
"FORCESTRAFE", // Translate turn inputs into strafe inputs
|
||||
"FORCESTRAFE", // Accessibility feature - is accelerate in kickstart mode?
|
||||
"CANCARRY",
|
||||
"HITFINISHLINE", // Already hit the finish line this tic
|
||||
"FINISHED",
|
||||
|
||||
NULL // stop loop here.
|
||||
};
|
||||
|
|
@ -12183,8 +12177,6 @@ static fixed_t find_const(const char **rword)
|
|||
free(word);
|
||||
return (1<<i);
|
||||
}
|
||||
if (fastcmp(p, "FULLSTASIS"))
|
||||
return PF_FULLSTASIS;
|
||||
|
||||
// Not found error
|
||||
const_warning("player flag",word);
|
||||
|
|
@ -12602,16 +12594,6 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (fastcmp(p, "FULLSTASIS"))
|
||||
{
|
||||
lua_pushinteger(L, (lua_Integer)PF_FULLSTASIS);
|
||||
return 1;
|
||||
}
|
||||
else if (fastcmp(p, "USEDOWN")) // Remove case when 2.3 nears release...
|
||||
{
|
||||
lua_pushinteger(L, (lua_Integer)PF_SPINDOWN);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "playerflag '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
33
src/g_demo.c
33
src/g_demo.c
|
|
@ -119,6 +119,7 @@ demoghost *ghosts = NULL;
|
|||
#define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode!
|
||||
|
||||
#define DEMO_SPECTATOR 0x40
|
||||
#define DEMO_KICKSTART 0x20
|
||||
|
||||
// For demos
|
||||
#define ZT_FWD 0x01
|
||||
|
|
@ -340,7 +341,13 @@ void G_ReadDemoExtraData(void)
|
|||
K_CheckBumpers();
|
||||
P_CheckRacers();
|
||||
}
|
||||
|
||||
if (extradata & DXD_WEAPONPREF)
|
||||
{
|
||||
extradata = READUINT8(demo_p);
|
||||
players[p].pflags &= ~(PF_KICKSTARTACCEL);
|
||||
if (extradata & 1)
|
||||
players[p].pflags |= PF_KICKSTARTACCEL;
|
||||
}
|
||||
|
||||
p = READUINT8(demo_p);
|
||||
}
|
||||
|
|
@ -446,6 +453,13 @@ void G_WriteDemoExtraData(void)
|
|||
else
|
||||
WRITEUINT8(demo_p, DXD_PST_PLAYING);
|
||||
}
|
||||
if (demo_extradata[i] & DXD_WEAPONPREF)
|
||||
{
|
||||
UINT8 prefs = 0;
|
||||
if (players[i].pflags & PF_KICKSTARTACCEL)
|
||||
prefs |= 1;
|
||||
WRITEUINT8(demo_p, prefs);
|
||||
}
|
||||
}
|
||||
|
||||
demo_extradata[i] = 0;
|
||||
|
|
@ -1067,6 +1081,8 @@ void G_GhostTicker(void)
|
|||
g->p += 32; // ok (32 because there's both the skin and the colour)
|
||||
if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING)
|
||||
I_Error("Ghost is not a record attack ghost PLAYSTATE"); //@TODO lmao don't blow up like this
|
||||
if (ziptic & DXD_WEAPONPREF)
|
||||
g->p++; // ditto
|
||||
}
|
||||
else if (ziptic == DW_RNG)
|
||||
g->p += 4; // RNG seed
|
||||
|
|
@ -1983,7 +1999,12 @@ void G_BeginRecording(void)
|
|||
if (playeringame[p]) {
|
||||
player = &players[p];
|
||||
|
||||
WRITEUINT8(demo_p, p | (player->spectator ? DEMO_SPECTATOR : 0));
|
||||
i = p;
|
||||
if (player->pflags & PF_KICKSTARTACCEL)
|
||||
i |= DEMO_KICKSTART;
|
||||
if (player->spectator)
|
||||
i |= DEMO_SPECTATOR;
|
||||
WRITEUINT8(demo_p, i);
|
||||
|
||||
// Name
|
||||
memset(name, 0, 16);
|
||||
|
|
@ -2903,6 +2924,12 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
while (p != 0xFF)
|
||||
{
|
||||
players[p].pflags &= ~PF_KICKSTARTACCEL;
|
||||
if (p & DEMO_KICKSTART)
|
||||
{
|
||||
players[p].pflags |= PF_KICKSTARTACCEL;
|
||||
p &= ~DEMO_KICKSTART;
|
||||
}
|
||||
spectator = false;
|
||||
if (p & DEMO_SPECTATOR)
|
||||
{
|
||||
|
|
@ -3194,7 +3221,7 @@ void G_AddGhost(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
|
||||
if (READUINT8(p) != 0)
|
||||
if ((READUINT8(p) & ~DEMO_KICKSTART) != 0)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
||||
Z_Free(pdemoname);
|
||||
|
|
|
|||
17
src/g_demo.h
17
src/g_demo.h
|
|
@ -110,16 +110,17 @@ typedef enum
|
|||
extern UINT8 demo_extradata[MAXPLAYERS];
|
||||
extern UINT8 demo_writerng;
|
||||
|
||||
#define DXD_RESPAWN 0x01 // "respawn" command in console
|
||||
#define DXD_SKIN 0x02 // skin changed
|
||||
#define DXD_NAME 0x04 // name changed
|
||||
#define DXD_COLOR 0x08 // color changed
|
||||
#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game
|
||||
#define DXD_FOLLOWER 0x20 // follower was changed
|
||||
#define DXD_RESPAWN 0x01 // "respawn" command in console
|
||||
#define DXD_SKIN 0x02 // skin changed
|
||||
#define DXD_NAME 0x04 // name changed
|
||||
#define DXD_COLOR 0x08 // color changed
|
||||
#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game
|
||||
#define DXD_FOLLOWER 0x20 // follower was changed
|
||||
#define DXD_WEAPONPREF 0x40 // netsynced playsim settings were changed
|
||||
|
||||
#define DXD_PST_PLAYING 0x01
|
||||
#define DXD_PST_PLAYING 0x01
|
||||
#define DXD_PST_SPECTATING 0x02
|
||||
#define DXD_PST_LEFT 0x03
|
||||
#define DXD_PST_LEFT 0x03
|
||||
|
||||
// Record/playback tics
|
||||
void G_ReadDemoExtraData(void);
|
||||
|
|
|
|||
105
src/g_game.c
105
src/g_game.c
|
|
@ -246,11 +246,11 @@ INT32 gameovertics = 15*TICRATE;
|
|||
UINT8 ammoremovaltics = 2*TICRATE;
|
||||
|
||||
// SRB2kart
|
||||
tic_t introtime = 0;
|
||||
tic_t starttime = 0;
|
||||
tic_t introtime = 3;
|
||||
tic_t starttime = 3;
|
||||
|
||||
const tic_t bulbtime = TICRATE/2;
|
||||
UINT8 numbulbs = 0;
|
||||
UINT8 numbulbs = 1;
|
||||
|
||||
tic_t raceexittime = 5*TICRATE + (2*TICRATE/3);
|
||||
tic_t battleexittime = 8*TICRATE;
|
||||
|
|
@ -342,10 +342,11 @@ INT16 prevmap, nextmap;
|
|||
|
||||
static UINT8 *savebuffer;
|
||||
|
||||
void SendWeaponPref(void);
|
||||
void SendWeaponPref2(void);
|
||||
void SendWeaponPref3(void);
|
||||
void SendWeaponPref4(void);
|
||||
static void kickstartaccel_OnChange(void);
|
||||
static void kickstartaccel2_OnChange(void);
|
||||
static void kickstartaccel3_OnChange(void);
|
||||
static void kickstartaccel4_OnChange(void);
|
||||
void SendWeaponPref(UINT8 n);
|
||||
|
||||
static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
|
||||
{1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"},
|
||||
|
|
@ -405,6 +406,13 @@ consvar_t cv_resetspecialmusic = CVAR_INIT ("resetspecialmusic", "Yes", CV_SAVE,
|
|||
|
||||
consvar_t cv_resume = CVAR_INIT ("resume", "Yes", CV_SAVE, CV_YesNo, NULL);
|
||||
|
||||
consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("kickstartaccel", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel_OnChange),
|
||||
CVAR_INIT ("kickstartaccel2", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel2_OnChange),
|
||||
CVAR_INIT ("kickstartaccel3", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel3_OnChange),
|
||||
CVAR_INIT ("kickstartaccel4", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel4_OnChange)
|
||||
};
|
||||
|
||||
consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("joyaxis_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
CVAR_INIT ("joyaxis2_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL),
|
||||
|
|
@ -1003,7 +1011,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
{
|
||||
// forward with key or button // SRB2kart - we use an accel/brake instead of forward/backward.
|
||||
axis = PlayerJoyAxis(ssplayer, AXISMOVE);
|
||||
if (PlayerInputDown(ssplayer, gc_accelerate) || (gamepadjoystickmove && axis > 0) || player->kartstuff[k_sneakertimer])
|
||||
if (PlayerInputDown(ssplayer, gc_accelerate) || (gamepadjoystickmove && axis > 0))
|
||||
{
|
||||
cmd->buttons |= BT_ACCELERATE;
|
||||
forward = MAXPLMOVE; // 50
|
||||
|
|
@ -1120,6 +1128,16 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
cmd->latency = modeattacking ? 0 : (leveltime & 0xFF); // Send leveltime when this tic was generated to the server for control lag calculations
|
||||
cmd->flags = 0;
|
||||
|
||||
if (chat_on || CON_Ready())
|
||||
{
|
||||
cmd->flags |= TICCMD_TYPING;
|
||||
|
||||
if (hu_keystrokes)
|
||||
{
|
||||
cmd->flags |= TICCMD_KEYSTROKE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lua: Allow this hook to overwrite ticcmd.
|
||||
We check if we're actually in a level because for some reason this Hook would run in menus and on the titlescreen otherwise.
|
||||
Be aware that within this hook, nothing but this player's cmd can be edited (otherwise we'd run in some pretty bad synching problems since this is clientsided, or something)
|
||||
|
|
@ -1174,6 +1192,26 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n)
|
|||
return dest;
|
||||
}
|
||||
|
||||
static void kickstartaccel_OnChange(void)
|
||||
{
|
||||
SendWeaponPref(0);
|
||||
}
|
||||
|
||||
static void kickstartaccel2_OnChange(void)
|
||||
{
|
||||
SendWeaponPref(1);
|
||||
}
|
||||
|
||||
static void kickstartaccel3_OnChange(void)
|
||||
{
|
||||
SendWeaponPref(2);
|
||||
}
|
||||
|
||||
static void kickstartaccel4_OnChange(void)
|
||||
{
|
||||
SendWeaponPref(3);
|
||||
}
|
||||
|
||||
//
|
||||
// G_DoLoadLevel
|
||||
//
|
||||
|
|
@ -1357,7 +1395,10 @@ boolean G_Responder(event_t *ev)
|
|||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
if (HU_Responder(ev))
|
||||
{
|
||||
hu_keystrokes = true;
|
||||
return true; // chat ate the event
|
||||
}
|
||||
if (AM_Responder(ev))
|
||||
return true; // automap ate it
|
||||
// map the event (key/mouse/joy) to a gamecontrol
|
||||
|
|
@ -1374,7 +1415,10 @@ boolean G_Responder(event_t *ev)
|
|||
else if (gamestate == GS_CUTSCENE)
|
||||
{
|
||||
if (HU_Responder(ev))
|
||||
{
|
||||
hu_keystrokes = true;
|
||||
return true; // chat ate the event
|
||||
}
|
||||
|
||||
if (F_CutsceneResponder(ev))
|
||||
{
|
||||
|
|
@ -1385,7 +1429,10 @@ boolean G_Responder(event_t *ev)
|
|||
else if (gamestate == GS_CREDITS || gamestate == GS_ENDING) // todo: keep ending here?
|
||||
{
|
||||
if (HU_Responder(ev))
|
||||
{
|
||||
hu_keystrokes = true;
|
||||
return true; // chat ate the event
|
||||
}
|
||||
|
||||
if (F_CreditResponder(ev))
|
||||
{
|
||||
|
|
@ -1408,7 +1455,10 @@ boolean G_Responder(event_t *ev)
|
|||
}
|
||||
else if (gamestate == GS_INTERMISSION || gamestate == GS_VOTING || gamestate == GS_EVALUATION)
|
||||
if (HU_Responder(ev))
|
||||
{
|
||||
hu_keystrokes = true;
|
||||
return true; // chat ate the event
|
||||
}
|
||||
|
||||
// allow spy mode changes even during the demo
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown
|
||||
|
|
@ -2084,6 +2134,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
INT32 wanted;
|
||||
boolean songcredit = false;
|
||||
boolean eliminated;
|
||||
UINT16 nocontrol;
|
||||
INT32 khudfault;
|
||||
INT32 kickstartaccel;
|
||||
|
||||
score = players[player].score;
|
||||
marescore = players[player].marescore;
|
||||
|
|
@ -2099,7 +2152,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
splitscreenindex = players[player].splitscreenindex;
|
||||
spectator = players[player].spectator;
|
||||
|
||||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_GAMETYPEOVER|PF_FAULT));
|
||||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_GAMETYPEOVER|PF_FAULT|PF_KICKSTARTACCEL));
|
||||
playerangleturn = players[player].angleturn;
|
||||
|
||||
// As long as we're not in multiplayer, carry over cheatcodes from map to map
|
||||
|
|
@ -2153,6 +2206,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
spheres = 0;
|
||||
eliminated = false;
|
||||
wanted = 0;
|
||||
kickstartaccel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2181,8 +2235,17 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
spheres = players[player].spheres;
|
||||
eliminated = players[player].eliminated;
|
||||
wanted = players[player].kartstuff[k_wanted];
|
||||
kickstartaccel = players[player].kickstartaccel;
|
||||
}
|
||||
|
||||
if (!betweenmaps)
|
||||
{
|
||||
khudfault = players[player].karthud[khud_fault];
|
||||
nocontrol = players[player].powers[pw_nocontrol];
|
||||
}
|
||||
else
|
||||
khudfault = nocontrol = 0;
|
||||
|
||||
// Obliterate follower from existence
|
||||
P_SetTarget(&players[player].follower, NULL);
|
||||
|
||||
|
|
@ -2244,6 +2307,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->kartstuff[k_wanted] = wanted;
|
||||
p->kartstuff[k_eggmanblame] = -1;
|
||||
p->kartstuff[k_lastdraft] = -1;
|
||||
p->karthud[khud_fault] = khudfault;
|
||||
p->powers[pw_nocontrol] = nocontrol;
|
||||
p->kickstartaccel = kickstartaccel;
|
||||
|
||||
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
|
||||
|
||||
|
|
@ -2258,9 +2324,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
|
||||
// Don't do anything immediately
|
||||
p->pflags |= PF_SPINDOWN;
|
||||
p->pflags |= PF_BRAKEDOWN;
|
||||
p->pflags |= PF_ATTACKDOWN;
|
||||
p->pflags |= PF_JUMPDOWN;
|
||||
p->pflags |= PF_ACCELDOWN;
|
||||
|
||||
p->playerstate = PST_LIVE;
|
||||
p->panim = PA_STILL; // standing animation
|
||||
|
|
@ -2297,6 +2363,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
if (betweenmaps)
|
||||
return;
|
||||
|
||||
if (leveltime < starttime)
|
||||
return;
|
||||
|
||||
if (p-players == consoleplayer)
|
||||
{
|
||||
if (mapmusflags & MUSIC_RELOADRESET)
|
||||
|
|
@ -2319,11 +2388,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
|
||||
if (songcredit)
|
||||
S_ShowMusicCredit();
|
||||
|
||||
if (leveltime > (starttime + (TICRATE/2)) && !p->spectator)
|
||||
{
|
||||
K_DoIngameRespawn(p);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -2385,10 +2449,17 @@ void G_SpawnPlayer(INT32 playernum)
|
|||
|
||||
void G_MovePlayerToSpawnOrStarpost(INT32 playernum)
|
||||
{
|
||||
#if 0
|
||||
if (leveltime <= introtime && !players[playernum].spectator)
|
||||
P_MovePlayerToSpawn(playernum, G_FindMapStart(playernum));
|
||||
else
|
||||
P_MovePlayerToStarpost(playernum);
|
||||
#else
|
||||
if (leveltime > starttime)
|
||||
P_MovePlayerToStarpost(playernum);
|
||||
else
|
||||
P_MovePlayerToSpawn(playernum, G_FindMapStart(playernum));
|
||||
#endif
|
||||
}
|
||||
|
||||
mapthing_t *G_FindTeamStart(INT32 playernum)
|
||||
|
|
@ -4407,7 +4478,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
|
|||
memset(&players[i].respawn, 0, sizeof (players[i].respawn));
|
||||
|
||||
// The latter two should clear by themselves, but just in case
|
||||
players[i].pflags &= ~(PF_GAMETYPEOVER|PF_FULLSTASIS|PF_FAULT);
|
||||
players[i].pflags &= ~(PF_GAMETYPEOVER|PF_STASIS|PF_FAULT);
|
||||
|
||||
// Clear cheatcodes too, just in case.
|
||||
players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ extern consvar_t cv_pauseifunfocused;
|
|||
|
||||
extern consvar_t cv_invertmouse;
|
||||
|
||||
extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS];
|
||||
|
|
|
|||
|
|
@ -478,7 +478,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
|||
|
||||
#ifdef GLENCORE
|
||||
if (encoremap)
|
||||
grtex->mipmap.colormap += (256*32);
|
||||
grtex->mipmap.colormap += COLORMAP_REMAPOFFSET;
|
||||
#endif
|
||||
|
||||
blockwidth = texture->width;
|
||||
|
|
@ -833,7 +833,7 @@ void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum, boolean noencoremap)
|
|||
|
||||
#ifdef GLENCORE
|
||||
if (!noencoremap && encoremap)
|
||||
grmip->colormap += (256*32);
|
||||
grmip->colormap += COLORMAP_REMAPOFFSET;
|
||||
#endif
|
||||
|
||||
grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
|
||||
|
|
|
|||
|
|
@ -219,7 +219,8 @@ enum EPolyFlags
|
|||
PF_Substractive = 0x00000010, // for splat
|
||||
PF_NoAlphaTest = 0x00000020, // hiden param
|
||||
PF_Fog = 0x00000040, // Fog blocks
|
||||
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest,
|
||||
PF_Invert = 0x00000080, // Polygon inverts the colours of what it's in front of
|
||||
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog|PF_Invert)&~PF_NoAlphaTest,
|
||||
|
||||
// other flag bits
|
||||
|
||||
|
|
|
|||
|
|
@ -697,6 +697,27 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height)
|
|||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||
}
|
||||
|
||||
void HWR_EncoreInvertScreen(void)
|
||||
{
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
|
||||
v[0].x = v[3].x = -1.0f;
|
||||
v[2].x = v[1].x = 1.0f;
|
||||
v[0].y = v[1].y = -1.0f;
|
||||
v[2].y = v[3].y = 1.0f;
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||
|
||||
v[0].s = v[3].s = 0.0f;
|
||||
v[2].s = v[1].s = 1.0f;
|
||||
v[0].t = v[1].t = 1.0f;
|
||||
v[2].t = v[3].t = 0.0f;
|
||||
|
||||
Surf.PolyColor.rgba = 0xFFFFFFFF;
|
||||
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Invert|PF_NoDepthTest);
|
||||
}
|
||||
|
||||
// Very similar to HWR_DrawConsoleBack, except we draw from the middle(-ish) of the screen to the bottom.
|
||||
void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5224,7 +5224,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->colormap = colormaps;
|
||||
#ifdef GLENCORE
|
||||
if (encoremap && (thing->flags & (MF_SCENERY|MF_NOTHINK)) && !(thing->flags & MF_DONTENCOREMAP))
|
||||
vis->colormap += (256*32);
|
||||
vis->colormap += COLORMAP_REMAPOFFSET;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -5331,7 +5331,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
|
||||
#ifdef GLENCORE
|
||||
if (encoremap && !(thing->flags & MF_DONTENCOREMAP))
|
||||
vis->colormap += (256*32);
|
||||
vis->colormap += COLORMAP_REMAPOFFSET;
|
||||
#endif
|
||||
|
||||
// set top/bottom coords
|
||||
|
|
@ -5526,6 +5526,11 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
else
|
||||
dometransform.flip = false;
|
||||
|
||||
if (*type == postimg_mirror)
|
||||
dometransform.mirror = true;
|
||||
else
|
||||
dometransform.mirror = false;
|
||||
|
||||
dometransform.scalex = 1;
|
||||
dometransform.scaley = (float)vid.width/vid.height;
|
||||
dometransform.scalez = 1;
|
||||
|
|
@ -5802,6 +5807,11 @@ void HWR_RenderSkyboxView(player_t *player)
|
|||
else
|
||||
atransform.flip = false;
|
||||
|
||||
if (*type == postimg_mirror)
|
||||
atransform.mirror = true;
|
||||
else
|
||||
atransform.mirror = false;
|
||||
|
||||
atransform.x = gl_viewx; // FIXED_TO_FLOAT(viewx)
|
||||
atransform.y = gl_viewy; // FIXED_TO_FLOAT(viewy)
|
||||
atransform.z = gl_viewz; // FIXED_TO_FLOAT(viewz)
|
||||
|
|
@ -6005,6 +6015,11 @@ void HWR_RenderPlayerView(void)
|
|||
else
|
||||
atransform.flip = false;
|
||||
|
||||
if (*type == postimg_mirror)
|
||||
atransform.mirror = true;
|
||||
else
|
||||
atransform.mirror = false;
|
||||
|
||||
atransform.x = gl_viewx; // FIXED_TO_FLOAT(viewx)
|
||||
atransform.y = gl_viewy; // FIXED_TO_FLOAT(viewy)
|
||||
atransform.z = gl_viewz; // FIXED_TO_FLOAT(viewz)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ void HWR_Shutdown(void);
|
|||
void HWR_drawAMline(const fline_t *fl, INT32 color);
|
||||
void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength);
|
||||
void HWR_DrawConsoleBack(UINT32 color, INT32 height);
|
||||
void HWR_EncoreInvertScreen(void);
|
||||
void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight);
|
||||
void HWR_RenderSkyboxView(player_t *player);
|
||||
void HWR_RenderPlayerView(void);
|
||||
|
|
|
|||
|
|
@ -1599,6 +1599,10 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
|
|||
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
|
||||
pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments
|
||||
break;
|
||||
case PF_Invert & PF_Invert:
|
||||
pglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
|
||||
pglAlphaFunc(GL_GREATER, 0.5f);
|
||||
break;
|
||||
default : // must be 0, otherwise it's an error
|
||||
// No blending
|
||||
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ patch_t *frameslash; // framerate stuff. Used in screen.c
|
|||
|
||||
static player_t *plr;
|
||||
boolean chat_on; // entering a chat message?
|
||||
boolean hu_keystrokes; // :)
|
||||
static char w_chat[HU_MAXMSGLEN];
|
||||
static size_t c_input = 0; // let's try to make the chat input less shitty.
|
||||
static boolean headsupactive = false;
|
||||
|
|
@ -879,6 +880,8 @@ void HU_Ticker(void)
|
|||
hu_showscores = !chat_on;
|
||||
else
|
||||
hu_showscores = false;
|
||||
|
||||
hu_keystrokes = false;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@ void HU_AddChatText(const char *text, boolean playsound);
|
|||
// set true when entering a chat message
|
||||
extern boolean chat_on;
|
||||
|
||||
// keystrokes in the console or chat window
|
||||
extern boolean hu_keystrokes;
|
||||
|
||||
extern patch_t *pinggfx[5];
|
||||
extern patch_t *framecounter;
|
||||
extern patch_t *frameslash;
|
||||
|
|
|
|||
|
|
@ -237,6 +237,8 @@ void K_UpdateMatchRaceBots(void)
|
|||
|
||||
while (numbots > wantedbots && i > 0)
|
||||
{
|
||||
i--;
|
||||
|
||||
if (playeringame[i] && players[i].bot)
|
||||
{
|
||||
buf[0] = i;
|
||||
|
|
@ -245,8 +247,6 @@ void K_UpdateMatchRaceBots(void)
|
|||
|
||||
numbots--;
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
129
src/k_hud.c
129
src/k_hud.c
|
|
@ -133,6 +133,9 @@ static patch_t *kp_check[6];
|
|||
static patch_t *kp_rival[2];
|
||||
static patch_t *kp_localtag[4][2];
|
||||
|
||||
static patch_t *kp_talk;
|
||||
static patch_t *kp_typdot;
|
||||
|
||||
static patch_t *kp_eggnum[4];
|
||||
|
||||
static patch_t *kp_flameshieldmeter[104][2];
|
||||
|
|
@ -503,6 +506,10 @@ void K_LoadKartHUDGraphics(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Typing indicator
|
||||
kp_talk = W_CachePatchName("K_TALK", PU_HUDGFX);
|
||||
kp_typdot = W_CachePatchName("K_TYPDOT", PU_HUDGFX);
|
||||
|
||||
// Eggman warning numbers
|
||||
sprintf(buffer, "K_EGGNx");
|
||||
for (i = 0; i < 4; i++)
|
||||
|
|
@ -816,7 +823,7 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu
|
|||
return;
|
||||
}
|
||||
|
||||
if (cam->chase == true)
|
||||
if (cam->chase == true && !player->spectator)
|
||||
{
|
||||
// Use the camera's properties.
|
||||
viewpointX = cam->x;
|
||||
|
|
@ -2193,6 +2200,63 @@ static void K_drawKartLapsAndRings(void)
|
|||
|
||||
#undef RINGANIM_FLIPFRAME
|
||||
|
||||
static void K_drawKartAccessibilityIcons(INT32 fx)
|
||||
{
|
||||
INT32 fy = LAPS_Y-25;
|
||||
UINT8 col = 0, i, wid, fil;
|
||||
INT32 splitflags = V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_SPLITSCREEN;
|
||||
//INT32 step = 1; -- if there's ever more than one accessibility icon
|
||||
|
||||
fx += LAPS_X;
|
||||
|
||||
if (r_splitscreen < 2) // adjust to speedometer height
|
||||
{
|
||||
if (gametype == GT_BATTLE)
|
||||
fy -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
fy += 4;
|
||||
if (!(stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]])) // If we are not P1 or P3...
|
||||
{
|
||||
splitflags ^= (V_SNAPTOLEFT|V_SNAPTORIGHT);
|
||||
fx = (BASEVIDWIDTH/2) - (fx + 10);
|
||||
//step = -step;
|
||||
}
|
||||
}
|
||||
|
||||
if (stplyr->pflags & PF_KICKSTARTACCEL) // just KICKSTARTACCEL right now, maybe more later
|
||||
{
|
||||
fil = 7-(stplyr->kickstartaccel*7)/ACCEL_KICKSTART;
|
||||
i = 7;
|
||||
|
||||
V_DrawFill(fx+4, fy-1, 2, 1, 31|V_SLIDEIN|splitflags);
|
||||
V_DrawFill(fx, (fy-1)+8, 10, 1, 31|V_SLIDEIN|splitflags);
|
||||
|
||||
while (i--)
|
||||
{
|
||||
wid = (i/2)+1;
|
||||
V_DrawFill(fx+4-wid, fy+i, 2+(wid*2), 1, 31|V_SLIDEIN|splitflags);
|
||||
if (fil)
|
||||
{
|
||||
if (i < fil)
|
||||
col = 23;
|
||||
else if (i == fil)
|
||||
col = 3;
|
||||
else
|
||||
col = 5 + (i-fil)*2;
|
||||
}
|
||||
else if ((leveltime % 7) == i)
|
||||
col = 0;
|
||||
else
|
||||
col = 3;
|
||||
V_DrawFill(fx+5-wid, fy+i, (wid*2), 1, col|V_SLIDEIN|splitflags);
|
||||
}
|
||||
|
||||
//fx += step*12;
|
||||
}
|
||||
}
|
||||
|
||||
static void K_drawKartSpeedometer(void)
|
||||
{
|
||||
static fixed_t convSpeed;
|
||||
|
|
@ -2242,6 +2306,8 @@ static void K_drawKartSpeedometer(void)
|
|||
V_DrawScaledPatch(LAPS_X+13, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[1]]);
|
||||
V_DrawScaledPatch(LAPS_X+19, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[numbers[2]]);
|
||||
V_DrawScaledPatch(LAPS_X+29, LAPS_Y-25 + battleoffset, V_HUDTRANS|V_SLIDEIN|splitflags, kp_speedometerlabel[labeln]);
|
||||
|
||||
K_drawKartAccessibilityIcons(56);
|
||||
}
|
||||
|
||||
static void K_drawBlueSphereMeter(void)
|
||||
|
|
@ -2598,6 +2664,27 @@ static void K_DrawRivalTagForPlayer(fixed_t x, fixed_t y)
|
|||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_rival[blink], NULL);
|
||||
}
|
||||
|
||||
static void K_DrawTypingDot(fixed_t x, fixed_t y, UINT8 duration, player_t *p)
|
||||
{
|
||||
if (p->typing_duration > duration)
|
||||
{
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_typdot, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_DrawTypingNotifier(fixed_t x, fixed_t y, player_t *p)
|
||||
{
|
||||
if (p->cmd.flags & TICCMD_TYPING)
|
||||
{
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_talk, NULL);
|
||||
|
||||
/* spacing closer with the last two looks a better most of the time */
|
||||
K_DrawTypingDot(x + 3*FRACUNIT, y, 15, p);
|
||||
K_DrawTypingDot(x + 6*FRACUNIT - FRACUNIT/3, y, 31, p);
|
||||
K_DrawTypingDot(x + 9*FRACUNIT - FRACUNIT/3, y, 47, p);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p, UINT8 cnum)
|
||||
{
|
||||
const INT32 clr = skincolors[p->skincolor].chatcolor;
|
||||
|
|
@ -2840,6 +2927,7 @@ static void K_drawKartNameTags(void)
|
|||
if (K_ShowPlayerNametag(ntplayer) == true)
|
||||
{
|
||||
K_DrawNameTagForPlayer(result.x, result.y, ntplayer, cnum);
|
||||
K_DrawTypingNotifier(result.x, result.y, ntplayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3632,7 +3720,27 @@ static void K_drawKartFirstPerson(void)
|
|||
const angle_t ang = R_PointToAngle2(0, 0, stplyr->rmomx, stplyr->rmomy) - stplyr->drawangle;
|
||||
// yes, the following is correct. no, you do not need to swap the x and y.
|
||||
fixed_t xoffs = -P_ReturnThrustY(stplyr->mo, ang, (BASEVIDWIDTH<<(FRACBITS-2))/2);
|
||||
fixed_t yoffs = -(P_ReturnThrustX(stplyr->mo, ang, 4*FRACUNIT) - 4*FRACUNIT);
|
||||
fixed_t yoffs = -P_ReturnThrustX(stplyr->mo, ang, 4*FRACUNIT);
|
||||
|
||||
// hitlag vibrating
|
||||
if (stplyr->mo->hitlag > 0)
|
||||
{
|
||||
fixed_t mul = stplyr->mo->hitlag * (FRACUNIT / 10);
|
||||
if (r_splitscreen && mul > FRACUNIT)
|
||||
mul = FRACUNIT;
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
mul = -mul;
|
||||
}
|
||||
|
||||
xoffs = FixedMul(xoffs, mul);
|
||||
yoffs = FixedMul(yoffs, mul);
|
||||
|
||||
}
|
||||
|
||||
if ((yoffs += 4*FRACUNIT) < 0)
|
||||
yoffs = 0;
|
||||
|
||||
if (r_splitscreen)
|
||||
xoffs = FixedMul(xoffs, scale);
|
||||
|
|
@ -4125,13 +4233,6 @@ void K_drawKartHUD(void)
|
|||
|
||||
if (!stplyr->spectator && !demo.freecam) // Bottom of the screen elements, don't need in spectate mode
|
||||
{
|
||||
// Draw the speedometer
|
||||
if (cv_kartspeedometer.value && !r_splitscreen)
|
||||
{
|
||||
if (LUA_HudEnabled(hud_speedometer))
|
||||
K_drawKartSpeedometer();
|
||||
}
|
||||
|
||||
if (demo.title) // Draw title logo instead in demo.titles
|
||||
{
|
||||
INT32 x = BASEVIDWIDTH - 32, y = 128, offs;
|
||||
|
|
@ -4182,6 +4283,16 @@ void K_drawKartHUD(void)
|
|||
K_drawKartBumpersOrKarma();
|
||||
}
|
||||
|
||||
// Draw the speedometer and/or accessibility icons
|
||||
if (cv_kartspeedometer.value && !r_splitscreen && (LUA_HudEnabled(hud_speedometer)))
|
||||
{
|
||||
K_drawKartSpeedometer();
|
||||
}
|
||||
else
|
||||
{
|
||||
K_drawKartAccessibilityIcons((r_splitscreen > 1) ? 0 : 8);
|
||||
}
|
||||
|
||||
if (gametyperules & GTR_SPHERES)
|
||||
{
|
||||
K_drawBlueSphereMeter();
|
||||
|
|
|
|||
144
src/k_kart.c
144
src/k_kart.c
|
|
@ -43,6 +43,63 @@
|
|||
// indirectitemcooldown is timer before anyone's allowed another Shrink/SPB
|
||||
// mapreset is set when enough players fill an empty server
|
||||
|
||||
void K_TimerReset(void)
|
||||
{
|
||||
starttime = introtime = 3;
|
||||
numbulbs = 1;
|
||||
}
|
||||
|
||||
void K_TimerInit(void)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 numPlayers = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (players[i].spectator == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
numPlayers++;
|
||||
}
|
||||
|
||||
if (numPlayers >= 2)
|
||||
{
|
||||
rainbowstartavailable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
rainbowstartavailable = false;
|
||||
}
|
||||
|
||||
if (numPlayers <= 2)
|
||||
{
|
||||
introtime = 0; // No intro in Record Attack / 1v1
|
||||
}
|
||||
else
|
||||
{
|
||||
introtime = (108) + 5; // 108 for rotation, + 5 for white fade
|
||||
}
|
||||
|
||||
numbulbs = 5;
|
||||
|
||||
if (numPlayers > 2)
|
||||
{
|
||||
numbulbs += (numPlayers-2);
|
||||
}
|
||||
|
||||
starttime = (introtime + (3*TICRATE)) + ((2*TICRATE) + (numbulbs * bulbtime)); // Start countdown time, + buffer time
|
||||
|
||||
// NOW you can try to spawn in the Battle capsules, if there's not enough players for a match
|
||||
K_SpawnBattleCapsules();
|
||||
}
|
||||
|
||||
UINT16 K_GetPlayerDontDrawFlag(player_t *player)
|
||||
{
|
||||
UINT16 flag = 0;
|
||||
|
|
@ -1845,19 +1902,19 @@ void K_KartMoveAnimation(player_t *player)
|
|||
|
||||
const boolean onground = P_IsObjectOnGround(player->mo);
|
||||
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
const boolean spinningwheels = (((cmd->buttons & BT_ACCELERATE) == BT_ACCELERATE) || (onground && player->speed > 0));
|
||||
const boolean lookback = ((cmd->buttons & BT_LOOKBACK) == BT_LOOKBACK);
|
||||
UINT16 buttons = K_GetKartButtons(player);
|
||||
const boolean spinningwheels = (((buttons & BT_ACCELERATE) == BT_ACCELERATE) || (onground && player->speed > 0));
|
||||
const boolean lookback = ((buttons & BT_LOOKBACK) == BT_LOOKBACK);
|
||||
|
||||
SINT8 turndir = 0;
|
||||
SINT8 destGlanceDir = 0;
|
||||
SINT8 drift = player->kartstuff[k_drift];
|
||||
|
||||
if (cmd->turning < -minturn)
|
||||
if (player->cmd.turning < -minturn)
|
||||
{
|
||||
turndir = -1;
|
||||
}
|
||||
else if (cmd->turning > minturn)
|
||||
else if (player->cmd.turning > minturn)
|
||||
{
|
||||
turndir = 1;
|
||||
}
|
||||
|
|
@ -2526,6 +2583,19 @@ UINT16 K_GetKartFlashing(player_t *player)
|
|||
return tics;
|
||||
}
|
||||
|
||||
boolean K_KartKickstart(player_t *player)
|
||||
{
|
||||
return ((player->pflags & PF_KICKSTARTACCEL)
|
||||
&& (!K_PlayerUsesBotMovement(player))
|
||||
&& (player->kickstartaccel >= ACCEL_KICKSTART));
|
||||
}
|
||||
|
||||
UINT16 K_GetKartButtons(player_t *player)
|
||||
{
|
||||
return (player->cmd.buttons |
|
||||
(K_KartKickstart(player) ? BT_ACCELERATE : 0));
|
||||
}
|
||||
|
||||
SINT8 K_GetForwardMove(player_t *player)
|
||||
{
|
||||
SINT8 forwardmove = player->cmd.forwardmove;
|
||||
|
|
@ -2545,6 +2615,13 @@ SINT8 K_GetForwardMove(player_t *player)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (K_KartKickstart(player)) // unlike the brute forward of sneakers, allow for backwards easing here
|
||||
{
|
||||
forwardmove += MAXPLMOVE;
|
||||
if (forwardmove > MAXPLMOVE)
|
||||
forwardmove = MAXPLMOVE;
|
||||
}
|
||||
|
||||
return forwardmove;
|
||||
}
|
||||
|
||||
|
|
@ -5575,7 +5652,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source)
|
|||
}
|
||||
|
||||
// Engine Sounds.
|
||||
static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
||||
static void K_UpdateEngineSounds(player_t *player)
|
||||
{
|
||||
const INT32 numsnds = 13;
|
||||
|
||||
|
|
@ -5584,6 +5661,8 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
const UINT8 dampenval = 48; // 255 * 48 = close enough to FRACUNIT/6
|
||||
|
||||
const UINT16 buttons = K_GetKartButtons(player);
|
||||
|
||||
INT32 class, s, w; // engine class number
|
||||
|
||||
UINT8 volume = 255;
|
||||
|
|
@ -5624,17 +5703,17 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
|||
if (player->respawn.state == RESPAWNST_DROP) // Dropdashing
|
||||
{
|
||||
// Dropdashing
|
||||
targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0);
|
||||
targetsnd = ((buttons & BT_ACCELERATE) ? 12 : 0);
|
||||
}
|
||||
else if (K_PlayerEBrake(player) == true)
|
||||
{
|
||||
// Spindashing
|
||||
targetsnd = ((cmd->buttons & BT_DRIFT) ? 12 : 0);
|
||||
targetsnd = ((buttons & BT_DRIFT) ? 12 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Average out the value of forwardmove and the speed that you're moving at.
|
||||
targetsnd = (((6 * cmd->forwardmove) / 25) + ((player->speed / mapobjectscale) / 5)) / 2;
|
||||
targetsnd = (((6 * K_GetForwardMove(player)) / 25) + ((player->speed / mapobjectscale) / 5)) / 2;
|
||||
}
|
||||
|
||||
if (targetsnd < 0) { targetsnd = 0; }
|
||||
|
|
@ -5932,7 +6011,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
K_UpdateOffroad(player);
|
||||
K_UpdateDraft(player);
|
||||
K_UpdateEngineSounds(player, cmd); // Thanks, VAda!
|
||||
K_UpdateEngineSounds(player); // Thanks, VAda!
|
||||
|
||||
// update boost angle if not spun out
|
||||
if (!player->kartstuff[k_spinouttimer] && !player->kartstuff[k_wipeoutslow])
|
||||
|
|
@ -6156,15 +6235,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
player->karthud[khud_timeovercam] = 0;
|
||||
|
||||
// Specific hack because it insists on setting flashing tics during this anyway...
|
||||
if (( player->kartstuff[k_spinouttype] & KSPIN_IFRAMES ) == 0)
|
||||
{
|
||||
player->powers[pw_flashing] = 0;
|
||||
}
|
||||
// Make ABSOLUTELY SURE that your flashing tics don't get set WHILE you're still in hit animations.
|
||||
else if (player->kartstuff[k_spinouttimer] != 0 || player->kartstuff[k_wipeoutslow] != 0)
|
||||
if (player->kartstuff[k_spinouttimer] != 0 || player->kartstuff[k_wipeoutslow] != 0)
|
||||
{
|
||||
player->powers[pw_flashing] = K_GetKartFlashing(player);
|
||||
if (( player->kartstuff[k_spinouttype] & KSPIN_IFRAMES ) == 0)
|
||||
player->powers[pw_flashing] = 0;
|
||||
else
|
||||
player->powers[pw_flashing] = K_GetKartFlashing(player);
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_spinouttimer])
|
||||
|
|
@ -6414,7 +6491,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
if (cmd->buttons & BT_DRIFT)
|
||||
{
|
||||
// Only allow drifting while NOT trying to do an spindash input.
|
||||
if ((cmd->buttons & BT_EBRAKEMASK) != BT_EBRAKEMASK)
|
||||
if ((K_GetKartButtons(player) & BT_EBRAKEMASK) != BT_EBRAKEMASK)
|
||||
{
|
||||
player->driftInput = true;
|
||||
}
|
||||
|
|
@ -6553,8 +6630,12 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
|||
|
||||
if (bestwaypoint == K_GetFinishLineWaypoint())
|
||||
{
|
||||
waypoint_t *nextwaypoint = waypoint->nextwaypoints[0];
|
||||
angle_t angletonextwaypoint =
|
||||
R_PointToAngle2(waypoint->mobj->x, waypoint->mobj->y, nextwaypoint->mobj->x, nextwaypoint->mobj->y);
|
||||
|
||||
// facing towards the finishline
|
||||
if (angledelta <= ANGLE_90)
|
||||
if (abs(AngleDifference(angletonextwaypoint, angletowaypoint)) <= ANGLE_90)
|
||||
{
|
||||
finishlinehack = true;
|
||||
}
|
||||
|
|
@ -6698,6 +6779,7 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
|||
return bestwaypoint;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_t *const player)
|
||||
{
|
||||
boolean nextiscloser = true;
|
||||
|
|
@ -6758,6 +6840,7 @@ static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_
|
|||
|
||||
return nextiscloser;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||
|
|
@ -6837,6 +6920,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
|||
|
||||
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
||||
|
||||
#if 0
|
||||
// An additional HACK, to fix looking backwards towards the finish line
|
||||
// If the player's next waypoint is the finishline and the angle distance from player to
|
||||
// connectin waypoints implies they're closer to a next waypoint, add a full track distance
|
||||
|
|
@ -6847,6 +6931,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
|||
player->distancetofinish += K_GetCircuitLength();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6951,10 +7036,15 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (player->respawn.state == RESPAWNST_MOVE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
currentSpeed = R_PointToDist2(0, 0, player->mo->momx, player->mo->momy);
|
||||
|
||||
if ((currentSpeed <= 0) // Not moving
|
||||
&& ((player->cmd.buttons & BT_EBRAKEMASK) != BT_EBRAKEMASK) // not e-braking
|
||||
&& ((K_GetKartButtons(player) & BT_EBRAKEMASK) != BT_EBRAKEMASK) // not e-braking
|
||||
&& (player->respawn.state == RESPAWNST_NONE)) // Not respawning
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -7058,6 +7148,8 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
const INT32 dstwo = dsone*2;
|
||||
const INT32 dsthree = dstwo*2;
|
||||
|
||||
const UINT16 buttons = K_GetKartButtons(player);
|
||||
|
||||
// Drifting is actually straffing + automatic turning.
|
||||
// Holding the Jump button will enable drifting.
|
||||
// (This comment is extremely funny)
|
||||
|
|
@ -7264,8 +7356,8 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
K_SpawnAIZDust(player);
|
||||
|
||||
if (player->kartstuff[k_drift]
|
||||
&& ((player->cmd.buttons & BT_BRAKE)
|
||||
|| !(player->cmd.buttons & BT_ACCELERATE))
|
||||
&& ((buttons & BT_BRAKE)
|
||||
|| !(buttons & BT_ACCELERATE))
|
||||
&& P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (!player->kartstuff[k_brakedrift])
|
||||
|
|
@ -7439,7 +7531,7 @@ static INT32 K_FlameShieldMax(player_t *player)
|
|||
|
||||
boolean K_PlayerEBrake(player_t *player)
|
||||
{
|
||||
return (player->cmd.buttons & BT_EBRAKEMASK) == BT_EBRAKEMASK
|
||||
return (K_GetKartButtons(player) & BT_EBRAKEMASK) == BT_EBRAKEMASK
|
||||
&& P_IsObjectOnGround(player->mo) == true
|
||||
&& player->kartstuff[k_drift] == 0
|
||||
&& player->kartstuff[k_spinouttimer] == 0
|
||||
|
|
@ -7622,8 +7714,6 @@ static void K_AirFailsafe(player_t *player)
|
|||
const fixed_t maxSpeed = 6*player->mo->scale;
|
||||
const fixed_t thrustSpeed = 6*player->mo->scale; // 10*player->mo->scale
|
||||
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
|
||||
if (player->speed > maxSpeed // Above the max speed that you're allowed to use this technique.
|
||||
|| player->respawn.state != RESPAWNST_NONE) // Respawning, you don't need this AND drop dash :V
|
||||
{
|
||||
|
|
@ -7631,7 +7721,7 @@ static void K_AirFailsafe(player_t *player)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((cmd->buttons & BT_ACCELERATE) || K_GetForwardMove(player) != 0)
|
||||
if ((K_GetKartButtons(player) & BT_ACCELERATE) || K_GetForwardMove(player) != 0)
|
||||
{
|
||||
// Queue up later
|
||||
player->airFailsafe = true;
|
||||
|
|
@ -7673,7 +7763,7 @@ void K_AdjustPlayerFriction(player_t *player)
|
|||
{
|
||||
player->mo->friction -= 1024;
|
||||
}
|
||||
else if (player->speed > 0 && cmd->forwardmove < 0)
|
||||
else if (player->speed > 0 && K_GetForwardMove(player) < 0)
|
||||
{
|
||||
player->mo->friction -= 512;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t
|
|||
|
||||
void K_RegisterKartStuff(void);
|
||||
|
||||
void K_TimerReset(void);
|
||||
void K_TimerInit(void);
|
||||
UINT16 K_GetPlayerDontDrawFlag(player_t *player);
|
||||
boolean K_IsPlayerLosing(player_t *player);
|
||||
fixed_t K_GetKartGameSpeedScalar(SINT8 value);
|
||||
|
|
@ -89,6 +91,8 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
|
|||
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
|
||||
fixed_t K_GetKartAccel(player_t *player);
|
||||
UINT16 K_GetKartFlashing(player_t *player);
|
||||
boolean K_KartKickstart(player_t *player);
|
||||
UINT16 K_GetKartButtons(player_t *player);
|
||||
SINT8 K_GetForwardMove(player_t *player);
|
||||
fixed_t K_3dKartMovement(player_t *player);
|
||||
boolean K_PlayerEBrake(player_t *player);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,21 @@ fixed_t K_RespawnOffset(player_t *player, boolean flip)
|
|||
return z;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_FudgeRespawn(player_t *player, const waypoint_t *const waypoint)
|
||||
|
||||
Fudges respawn coordinates to slightly before the waypoint if it would
|
||||
be exactly on a line. See K_GetWaypointIsOnLine.
|
||||
--------------------------------------------------*/
|
||||
static void K_FudgeRespawn(player_t *player, const waypoint_t *const waypoint)
|
||||
{
|
||||
const angle_t from = R_PointToAngle2(waypoint->mobj->x, waypoint->mobj->y,
|
||||
player->mo->x, player->mo->y) >> ANGLETOFINESHIFT;
|
||||
|
||||
player->respawn.pointx += FixedMul(16, FINECOSINE(from));
|
||||
player->respawn.pointy += FixedMul(16, FINESINE(from));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
|
||||
|
|
@ -83,6 +98,28 @@ static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
|||
player->respawn.pointz = waypoint->mobj->z;
|
||||
player->respawn.flip = (waypoint->mobj->flags2 & MF2_OBJECTFLIP) ? true : false; // K_RespawnOffset wants a boolean!
|
||||
player->respawn.pointz += K_RespawnOffset(player, player->respawn.flip);
|
||||
|
||||
if (waypoint->onaline)
|
||||
{
|
||||
K_FudgeRespawn(player, waypoint);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_DoFault(player_t *player)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_DoFault(player_t *player)
|
||||
{
|
||||
player->powers[pw_nocontrol] = (starttime - leveltime) + 50;
|
||||
if (!(player->pflags & PF_FAULT))
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s3k83);
|
||||
player->karthud[khud_fault] = 1;
|
||||
player->pflags |= PF_FAULT;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -103,18 +140,14 @@ void K_DoIngameRespawn(player_t *player)
|
|||
return;
|
||||
}
|
||||
|
||||
if (leveltime < introtime)
|
||||
if (leveltime <= introtime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (leveltime < starttime) // FAULT
|
||||
{
|
||||
player->powers[pw_nocontrol] = (starttime - leveltime) + 50;
|
||||
player->pflags |= PF_FAULT;
|
||||
S_StartSound(player->mo, sfx_s3k83);
|
||||
player->karthud[khud_fault] = 1;
|
||||
}
|
||||
// FAULT
|
||||
if (leveltime < starttime)
|
||||
K_DoFault(player);
|
||||
|
||||
player->kartstuff[k_ringboost] = 0;
|
||||
player->kartstuff[k_driftboost] = 0;
|
||||
|
|
@ -338,6 +371,12 @@ static void K_MovePlayerToRespawnPoint(player_t *player)
|
|||
}
|
||||
|
||||
// Set angle, regardless of if we're done or not
|
||||
P_SetPlayerAngle(player, R_PointToAngle2(
|
||||
player->respawn.wp->mobj->x,
|
||||
player->respawn.wp->mobj->y,
|
||||
player->respawn.wp->nextwaypoints[nwp]->mobj->x,
|
||||
player->respawn.wp->nextwaypoints[nwp]->mobj->y
|
||||
));
|
||||
player->drawangle = R_PointToAngle2(
|
||||
player->mo->x, player->mo->y,
|
||||
dest.x, dest.y
|
||||
|
|
@ -615,7 +654,7 @@ static void K_DropDashWait(player_t *player)
|
|||
--------------------------------------------------*/
|
||||
static void K_HandleDropDash(player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
const UINT16 buttons = K_GetKartButtons(player);
|
||||
|
||||
if (player->kartstuff[k_growshrinktimer] < 0)
|
||||
{
|
||||
|
|
@ -640,7 +679,7 @@ static void K_HandleDropDash(player_t *player)
|
|||
// The old behavior was stupid and prone to accidental usage.
|
||||
// Let's rip off Mania instead, and turn this into a Drop Dash!
|
||||
|
||||
if ((cmd->buttons & BT_ACCELERATE) && !player->kartstuff[k_spinouttimer]) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway)
|
||||
if ((buttons & BT_ACCELERATE) && !player->kartstuff[k_spinouttimer]) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway)
|
||||
{
|
||||
player->respawn.dropdash++;
|
||||
}
|
||||
|
|
@ -665,7 +704,7 @@ static void K_HandleDropDash(player_t *player)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((cmd->buttons & BT_ACCELERATE) && (player->respawn.dropdash >= TICRATE/4))
|
||||
if ((buttons & BT_ACCELERATE) && (player->respawn.dropdash >= TICRATE/4))
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s23c);
|
||||
player->kartstuff[k_startboost] = 50;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,21 @@
|
|||
fixed_t K_RespawnOffset(player_t *player, boolean flip);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_DoFault(player_t *player);
|
||||
|
||||
Faults the specified player.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform this for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_DoFault(player_t *player);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_DoIngameRespawn(player_t *player);
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,38 @@ boolean K_GetWaypointIsSpawnpoint(waypoint_t *waypoint)
|
|||
return waypointisspawnpoint;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_GetWaypointIsOnLine(waypoint_t *const waypoint)
|
||||
|
||||
Checks if a waypoint is exactly on a line. Moving to an exact point
|
||||
on a line won't count as crossing it. Moving off of that point does.
|
||||
Respawning to a waypoint which is exactly on a line is the easiest
|
||||
way to for this to occur.
|
||||
|
||||
Return:-
|
||||
Whether the waypoint is exactly on a line.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_GetWaypointIsOnLine(waypoint_t *const waypoint)
|
||||
{
|
||||
const fixed_t x = waypoint->mobj->x;
|
||||
const fixed_t y = waypoint->mobj->y;
|
||||
|
||||
line_t *line = P_FindNearestLine(x, y,
|
||||
waypoint->mobj->subsector->sector, -1);
|
||||
|
||||
vertex_t point;
|
||||
|
||||
if (line != NULL)
|
||||
{
|
||||
P_ClosestPointOnLine(x, y, line, &point);
|
||||
|
||||
if (x == point.x && y == point.y)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
INT32 K_GetWaypointNextID(waypoint_t *waypoint)
|
||||
|
||||
|
|
@ -253,6 +285,40 @@ waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
|
|||
return closestwaypoint;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_CompareOverlappingWaypoint
|
||||
( waypoint_t *const checkwaypoint,
|
||||
waypoint_t **const bestwaypoint,
|
||||
fixed_t *const bestfindist)
|
||||
|
||||
Solves touching overlapping waypoint radiuses by sorting by distance to
|
||||
finish line.
|
||||
--------------------------------------------------*/
|
||||
static void K_CompareOverlappingWaypoint
|
||||
( waypoint_t *const checkwaypoint,
|
||||
waypoint_t **const bestwaypoint,
|
||||
fixed_t *const bestfindist)
|
||||
{
|
||||
const boolean useshortcuts = false;
|
||||
const boolean huntbackwards = false;
|
||||
boolean pathfindsuccess = false;
|
||||
path_t pathtofinish = {};
|
||||
|
||||
pathfindsuccess =
|
||||
K_PathfindToWaypoint(checkwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards);
|
||||
|
||||
if (pathfindsuccess == true)
|
||||
{
|
||||
if ((INT32)(pathtofinish.totaldist) < *bestfindist)
|
||||
{
|
||||
*bestwaypoint = checkwaypoint;
|
||||
*bestfindist = pathtofinish.totaldist;
|
||||
}
|
||||
|
||||
Z_Free(pathtofinish.array);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
||||
|
||||
|
|
@ -292,30 +358,18 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
|
|||
|
||||
rad = (checkwaypoint->mobj->radius / FRACUNIT);
|
||||
|
||||
if (closestdist < rad && checkdist < rad && finishline != NULL)
|
||||
// remember: huge radius
|
||||
if (closestdist <= rad && checkdist <= rad && finishline != NULL)
|
||||
{
|
||||
const boolean useshortcuts = false;
|
||||
const boolean huntbackwards = false;
|
||||
boolean pathfindsuccess = false;
|
||||
path_t pathtofinish = {};
|
||||
|
||||
// If the mobj is touching multiple waypoints at once,
|
||||
// then solve ties by taking the one closest to the finish line.
|
||||
// Prevents position from flickering wildly when taking turns.
|
||||
|
||||
pathfindsuccess =
|
||||
K_PathfindToWaypoint(checkwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards);
|
||||
// For the first couple overlapping, check the previous best too.
|
||||
if (bestfindist == INT32_MAX)
|
||||
K_CompareOverlappingWaypoint(bestwaypoint, &bestwaypoint, &bestfindist);
|
||||
|
||||
if (pathfindsuccess == true)
|
||||
{
|
||||
if ((INT32)(pathtofinish.totaldist) < bestfindist)
|
||||
{
|
||||
bestwaypoint = checkwaypoint;
|
||||
bestfindist = pathtofinish.totaldist;
|
||||
}
|
||||
|
||||
Z_Free(pathtofinish.array);
|
||||
}
|
||||
K_CompareOverlappingWaypoint(checkwaypoint, &bestwaypoint, &bestfindist);
|
||||
}
|
||||
else if (checkdist < closestdist && bestfindist == INT32_MAX)
|
||||
{
|
||||
|
|
@ -1678,6 +1732,12 @@ static waypoint_t *K_SetupWaypoint(mobj_t *const mobj)
|
|||
finishline = thiswaypoint;
|
||||
}
|
||||
|
||||
/* only relevant for respawning */
|
||||
if (K_GetWaypointIsSpawnpoint(thiswaypoint))
|
||||
{
|
||||
thiswaypoint->onaline = K_GetWaypointIsOnLine(thiswaypoint);
|
||||
}
|
||||
|
||||
if (thiswaypoint->numnextwaypoints > 0)
|
||||
{
|
||||
waypoint_t *nextwaypoint = NULL;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
typedef struct waypoint_s
|
||||
{
|
||||
mobj_t *mobj;
|
||||
boolean onaline;
|
||||
struct waypoint_s **nextwaypoints;
|
||||
struct waypoint_s **prevwaypoints;
|
||||
UINT32 *nextwaypointdistances;
|
||||
|
|
|
|||
|
|
@ -1195,8 +1195,8 @@ static int lib_pGivePlayerRings(lua_State *L)
|
|||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_GivePlayerRings(player, num_rings);
|
||||
return 0;
|
||||
lua_pushinteger(L, P_GivePlayerRings(player, num_rings));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pGivePlayerLives(lua_State *L)
|
||||
|
|
@ -1491,17 +1491,6 @@ static int lib_pDoSpring(lua_State *L)
|
|||
// P_INTER
|
||||
////////////
|
||||
|
||||
static int lib_pRemoveShield(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_RemoveShield(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pDamageMobj(lua_State *L)
|
||||
{
|
||||
mobj_t *target = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)), *inflictor = NULL, *source = NULL;
|
||||
|
|
@ -3803,7 +3792,6 @@ static luaL_Reg lib[] = {
|
|||
{"P_DoSpring",lib_pDoSpring},
|
||||
|
||||
// p_inter
|
||||
{"P_RemoveShield",lib_pRemoveShield},
|
||||
{"P_DamageMobj",lib_pDamageMobj},
|
||||
{"P_KillMobj",lib_pKillMobj},
|
||||
{"P_PlayerRingBurst",lib_pPlayerRingBurst},
|
||||
|
|
|
|||
|
|
@ -4186,10 +4186,8 @@ void A_AttractChase(mobj_t *actor)
|
|||
{
|
||||
if (actor->extravalue1 >= 16)
|
||||
{
|
||||
if (actor->target->player->rings >= 20)
|
||||
if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed
|
||||
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player)+3;
|
||||
else
|
||||
P_GivePlayerRings(actor->target->player, 1);
|
||||
|
||||
if (actor->cvmem) // caching
|
||||
S_StartSound(actor->target, sfx_s1c5);
|
||||
|
|
|
|||
|
|
@ -1370,6 +1370,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
break;
|
||||
|
||||
case MT_PLAYER:
|
||||
if (damagetype != DMG_SPECTATOR)
|
||||
{
|
||||
angle_t flingAngle;
|
||||
mobj_t *kart;
|
||||
|
|
@ -1750,8 +1751,15 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
// Respawn kill types
|
||||
K_DoIngameRespawn(player);
|
||||
return false;
|
||||
case DMG_SPECTATOR:
|
||||
// disappearifies, but still gotta put items back in play
|
||||
break;
|
||||
default:
|
||||
// Everything else REALLY kills
|
||||
if (leveltime < starttime)
|
||||
{
|
||||
K_DoFault(player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1795,35 +1803,6 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
|||
return true;
|
||||
}
|
||||
|
||||
void P_RemoveShield(player_t *player)
|
||||
{
|
||||
if (player->powers[pw_shield] & SH_FORCE)
|
||||
{ // Multi-hit
|
||||
if (player->powers[pw_shield] & SH_FORCEHP)
|
||||
player->powers[pw_shield]--;
|
||||
else
|
||||
player->powers[pw_shield] &= SH_STACK;
|
||||
}
|
||||
else if (player->powers[pw_shield] & SH_NOSTACK)
|
||||
{ // First layer shields
|
||||
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) // Give them what's coming to them!
|
||||
{
|
||||
player->pflags |= PF_JUMPDOWN;
|
||||
}
|
||||
else
|
||||
player->powers[pw_shield] &= SH_STACK;
|
||||
}
|
||||
else
|
||||
{ // Second layer shields
|
||||
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !player->powers[pw_super])
|
||||
{
|
||||
player->mo->color = player->skincolor;
|
||||
G_GhostAddColor((INT32) (player - players), GHC_NORMAL);
|
||||
}
|
||||
player->powers[pw_shield] = SH_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/** Damages an object, which may or may not be a player.
|
||||
* For melee attacks, source and inflictor are the same.
|
||||
*
|
||||
|
|
@ -2138,7 +2117,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
static void P_FlingBurst
|
||||
( player_t *player,
|
||||
angle_t fa,
|
||||
fixed_t z,
|
||||
mobjtype_t objType,
|
||||
tic_t objFuse,
|
||||
fixed_t objScale,
|
||||
|
|
@ -2149,18 +2127,17 @@ static void P_FlingBurst
|
|||
fixed_t momxy = 5<<FRACBITS, momz = 12<<FRACBITS; // base horizonal/vertical thrusts
|
||||
INT32 mx = (i + 1) >> 1;
|
||||
|
||||
z = player->mo->z;
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
z += player->mo->height - mobjinfo[objType].height;
|
||||
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, z, objType);
|
||||
mo = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, objType);
|
||||
|
||||
mo->threshold = 10; // not useful for spikes
|
||||
mo->fuse = objFuse;
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
|
||||
mo->destscale = objScale;
|
||||
P_SetScale(mo, objScale);
|
||||
if (objScale != FRACUNIT)
|
||||
{
|
||||
P_SetScale(mo, FixedMul(objScale, mo->scale));
|
||||
mo->destscale = mo->scale;
|
||||
}
|
||||
|
||||
/*
|
||||
0: 0
|
||||
|
|
@ -2197,7 +2174,6 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
INT32 num_fling_rings;
|
||||
INT32 i;
|
||||
angle_t fa;
|
||||
fixed_t z;
|
||||
|
||||
// Rings shouldn't be in Battle!
|
||||
if (gametyperules & GTR_SPHERES)
|
||||
|
|
@ -2211,32 +2187,25 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
|||
if (K_GetShieldFromItem(player->kartstuff[k_itemtype]) != KSHIELD_NONE)
|
||||
return;
|
||||
|
||||
// 20 is the ring cap in kart
|
||||
// 20 is the maximum number of rings that can be taken from you at once - half the span of your counter
|
||||
if (num_rings > 20)
|
||||
num_rings = 20;
|
||||
else if (num_rings <= 0)
|
||||
return;
|
||||
|
||||
num_fling_rings = min(num_rings, player->rings);
|
||||
|
||||
P_GivePlayerRings(player, -num_rings);
|
||||
num_rings = -P_GivePlayerRings(player, -num_rings);
|
||||
num_fling_rings = num_rings+min(0, player->rings);
|
||||
|
||||
// determine first angle
|
||||
fa = player->mo->angle + ((P_RandomByte() & 1) ? -ANGLE_90 : ANGLE_90);
|
||||
|
||||
z = player->mo->z;
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
z += player->mo->height - mobjinfo[MT_RING].height;
|
||||
|
||||
for (i = 0; i < num_fling_rings; i++)
|
||||
{
|
||||
P_FlingBurst(player, fa, z,
|
||||
MT_FLINGRING, 60*TICRATE, player->mo->scale, i);
|
||||
P_FlingBurst(player, fa, MT_FLINGRING, 60*TICRATE, FRACUNIT, i);
|
||||
}
|
||||
|
||||
while (i < num_rings)
|
||||
{
|
||||
P_FlingBurst(player, fa, z,
|
||||
MT_DEBTSPIKE, 0, 3 * player->mo->scale / 2, i++);
|
||||
P_FlingBurst(player, fa, MT_DEBTSPIKE, 0, 3 * FRACUNIT / 2, i++);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ boolean P_IsObjectInGoop(mobj_t *mo);
|
|||
boolean P_IsObjectOnGround(mobj_t *mo);
|
||||
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
|
||||
boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec); // SRB2Kart
|
||||
#define P_IsObjectFlipped(o) ((o)->eflags & MFE_VERTICALFLIP)
|
||||
boolean P_InQuicksand(mobj_t *mo);
|
||||
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
|
||||
|
||||
|
|
@ -167,7 +168,7 @@ boolean P_EndingMusic(player_t *player);
|
|||
void P_SpawnShieldOrb(player_t *player);
|
||||
void P_SwitchShield(player_t *player, UINT16 shieldtype);
|
||||
mobj_t *P_SpawnGhostMobj(mobj_t *mobj);
|
||||
void P_GivePlayerRings(player_t *player, INT32 num_rings);
|
||||
INT32 P_GivePlayerRings(player_t *player, INT32 num_rings);
|
||||
void P_GivePlayerSpheres(player_t *player, INT32 num_spheres);
|
||||
void P_GivePlayerLives(player_t *player, INT32 numlives);
|
||||
UINT8 P_GetNextEmerald(void);
|
||||
|
|
@ -485,7 +486,6 @@ typedef struct BasicFF_s
|
|||
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period);
|
||||
void P_ForceConstant(const BasicFF_t *FFInfo);
|
||||
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End);
|
||||
void P_RemoveShield(player_t *player);
|
||||
void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
|
||||
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype);
|
||||
|
|
@ -521,5 +521,9 @@ void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move);
|
|||
void P_ExplodeMissile(mobj_t *mo);
|
||||
void P_CheckGravity(mobj_t *mo, boolean affect);
|
||||
void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope);
|
||||
fixed_t P_ScaleFromMap(fixed_t n, fixed_t scale);
|
||||
fixed_t P_GetMobjHead(const mobj_t *);
|
||||
fixed_t P_GetMobjFeet(const mobj_t *);
|
||||
fixed_t P_GetMobjGround(const mobj_t *);
|
||||
|
||||
#endif // __P_LOCAL__
|
||||
|
|
|
|||
|
|
@ -259,6 +259,76 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
|
|||
return frac;
|
||||
}
|
||||
|
||||
static fixed_t dist2line(const line_t *ld, const fixed_t x, const fixed_t y)
|
||||
{
|
||||
return FixedHypot
|
||||
(
|
||||
ld->v1->x + (ld->dx / 2) - x,
|
||||
ld->v1->y + (ld->dy / 2) - y
|
||||
);
|
||||
}
|
||||
|
||||
static void checknearline
|
||||
( line_t * line,
|
||||
fixed_t * nearest,
|
||||
line_t ** near_line,
|
||||
const fixed_t x,
|
||||
const fixed_t y)
|
||||
{
|
||||
const fixed_t d = dist2line(line, x, y);
|
||||
|
||||
if (d < *nearest)
|
||||
{
|
||||
*nearest = d;
|
||||
*near_line = line;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_FindNearestLine
|
||||
// Returns the nearest line to a point which
|
||||
// is in a sector and/or a specific type.
|
||||
//
|
||||
line_t * P_FindNearestLine
|
||||
( const fixed_t x,
|
||||
const fixed_t y,
|
||||
const sector_t * sector,
|
||||
const INT32 special)
|
||||
{
|
||||
fixed_t nearest = INT32_MAX;
|
||||
line_t *near_line = NULL;
|
||||
size_t i;
|
||||
INT32 line = -1;
|
||||
|
||||
if (special == -1)
|
||||
{
|
||||
if (sector == NULL)
|
||||
sector = R_PointInSubsector(x, y)->sector;
|
||||
|
||||
for (i = 0; i < sector->linecount; ++i)
|
||||
{
|
||||
checknearline(sector->lines[i], &nearest, &near_line, x, y);
|
||||
}
|
||||
}
|
||||
else if (sector != NULL)
|
||||
{
|
||||
for (i = 0; i < sector->linecount; ++i)
|
||||
{
|
||||
if (sector->lines[i]->special == special)
|
||||
checknearline(sector->lines[i], &nearest, &near_line, x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((line = P_FindSpecialLineFromTag(special, -1, line)) != -1)
|
||||
{
|
||||
checknearline(&lines[line], &nearest, &near_line, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return near_line;
|
||||
}
|
||||
|
||||
//
|
||||
// P_LineOpening
|
||||
// Sets opentop and openbottom to the window through a two sided line.
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ void P_MakeDivline(line_t *li, divline_t *dl);
|
|||
void P_CameraLineOpening(line_t *plinedef);
|
||||
fixed_t P_InterceptVector(divline_t *v2, divline_t *v1);
|
||||
INT32 P_BoxOnLineSide(fixed_t *tmbox, line_t *ld);
|
||||
line_t * P_FindNearestLine(const fixed_t x, const fixed_t y, const sector_t *, const INT32 special);
|
||||
void P_UnsetPrecipThingPosition(precipmobj_t *thing);
|
||||
void P_SetPrecipitationThingPosition(precipmobj_t *thing);
|
||||
void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y);
|
||||
|
|
|
|||
83
src/p_mobj.c
83
src/p_mobj.c
|
|
@ -2296,11 +2296,6 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
{
|
||||
mom.x = mom.y = 0;
|
||||
mom.z = -mom.z/2;
|
||||
|
||||
if (mo->fuse == 0)
|
||||
{
|
||||
mo->fuse = 90;
|
||||
}
|
||||
}
|
||||
else if (mo->flags & MF_MISSILE)
|
||||
{
|
||||
|
|
@ -6267,6 +6262,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
else
|
||||
A_AttractChase(mobj);
|
||||
break;
|
||||
case MT_DEBTSPIKE:
|
||||
if (mobj->fuse == 0 && P_GetMobjFeet(mobj) == P_GetMobjGround(mobj))
|
||||
{
|
||||
mobj->fuse = 90;
|
||||
}
|
||||
break;
|
||||
case MT_EMBLEM:
|
||||
if (mobj->flags2 & MF2_NIGHTSPULL)
|
||||
P_NightsItemChase(mobj);
|
||||
|
|
@ -6838,7 +6839,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target))
|
||||
|| !mobj->target->player->kartstuff[k_drift] || !mobj->target->player->kartstuff[k_brakedrift]
|
||||
|| !((mobj->target->player->cmd.buttons & BT_BRAKE)
|
||||
|| !(mobj->target->player->cmd.buttons & BT_ACCELERATE))) // Letting go of accel functions about the same as brake-drifting
|
||||
|| (K_GetKartButtons(mobj->target->player) & BT_ACCELERATE))) // Letting go of accel functions about the same as brake-drifting
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
|
|
@ -10591,7 +10592,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
|
|||
{
|
||||
fixed_t offset = mthing->z << FRACBITS;
|
||||
|
||||
if (p->respawn.state != RESPAWNST_NONE)
|
||||
if (p->respawn.state != RESPAWNST_NONE || p->spectator)
|
||||
offset += K_RespawnOffset(p, (mthing->options & MTF_OBJECTFLIP));
|
||||
|
||||
// Flagging a player's ambush will make them start on the ceiling
|
||||
|
|
@ -10637,6 +10638,12 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
|
|||
|
||||
mobj->angle = angle;
|
||||
|
||||
// FAULT
|
||||
if (leveltime > introtime && !p->spectator)
|
||||
{
|
||||
K_DoIngameRespawn(p);
|
||||
}
|
||||
|
||||
P_AfterPlayerSpawn(playernum);
|
||||
}
|
||||
|
||||
|
|
@ -10690,6 +10697,8 @@ void P_MovePlayerToStarpost(INT32 playernum)
|
|||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
p->drawangle = mobj->angle; // default to the camera angle
|
||||
|
||||
P_AfterPlayerSpawn(playernum);
|
||||
}
|
||||
|
|
@ -11325,6 +11334,18 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void P_SnapToFinishLine(mobj_t *mobj)
|
||||
{
|
||||
line_t *finishline = P_FindNearestLine(mobj->x, mobj->y,
|
||||
mobj->subsector->sector, 2001); // case 2001: Finish Line
|
||||
if (finishline != NULL)
|
||||
{
|
||||
P_UnsetThingPosition(mobj);
|
||||
P_ClosestPointOnLine(mobj->x, mobj->y, finishline, (vertex_t *)&mobj->x);
|
||||
P_SetThingPosition(mobj);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
|
||||
{
|
||||
boolean override = LUAh_MapThingSpawn(mobj, mthing);
|
||||
|
|
@ -11708,7 +11729,10 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
}
|
||||
if (mthing->args[2] == 1)
|
||||
{
|
||||
mobj->extravalue2 = 1; // args[1] of 1 means the waypoint is at the finish line
|
||||
mobj->extravalue2 = 1; // args[2] of 1 means the waypoint is at the finish line
|
||||
mobj->reactiontime = 0; // Also don't respawn at finish lines
|
||||
|
||||
P_SnapToFinishLine(mobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -12748,6 +12772,15 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration)
|
|||
pl->flashpal = type;
|
||||
}
|
||||
|
||||
//
|
||||
// P_ScaleFromMap
|
||||
// Scales a number relative to the mapobjectscale.
|
||||
//
|
||||
fixed_t P_ScaleFromMap(fixed_t n, fixed_t scale)
|
||||
{
|
||||
return FixedMul(n, FixedDiv(scale, mapobjectscale));
|
||||
}
|
||||
|
||||
//
|
||||
// P_SpawnMobjFromMobj
|
||||
// Spawns an object with offsets relative to the position of another object.
|
||||
|
|
@ -12765,16 +12798,40 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
|
|||
if (!newmobj)
|
||||
return NULL;
|
||||
|
||||
newmobj->destscale = P_ScaleFromMap(mobj->destscale, newmobj->destscale);
|
||||
P_SetScale(newmobj, P_ScaleFromMap(mobj->scale, newmobj->scale));
|
||||
|
||||
if (mobj->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
fixed_t elementheight = FixedMul(newmobj->info->height, mobj->scale);
|
||||
|
||||
newmobj->eflags |= MFE_VERTICALFLIP;
|
||||
newmobj->flags2 |= MF2_OBJECTFLIP;
|
||||
newmobj->z = mobj->z + mobj->height - zofs - elementheight;
|
||||
newmobj->z = mobj->z + mobj->height - zofs - newmobj->height;
|
||||
}
|
||||
|
||||
newmobj->destscale = mobj->destscale;
|
||||
P_SetScale(newmobj, mobj->scale);
|
||||
return newmobj;
|
||||
}
|
||||
|
||||
//
|
||||
// P_GetMobjHead & P_GetMobjFeet
|
||||
// Returns the top and bottom of an object, follows appearance, not physics,
|
||||
// in reverse gravity.
|
||||
//
|
||||
|
||||
fixed_t P_GetMobjHead(const mobj_t *mobj)
|
||||
{
|
||||
return P_IsObjectFlipped(mobj) ? mobj->z : mobj->z + mobj->height;
|
||||
}
|
||||
|
||||
fixed_t P_GetMobjFeet(const mobj_t *mobj)
|
||||
{
|
||||
return P_IsObjectFlipped(mobj) ? mobj->z + mobj->height : mobj->z;
|
||||
}
|
||||
|
||||
//
|
||||
// P_GetMobjGround
|
||||
// Returns the object's floor, or ceiling in reverse gravity.
|
||||
//
|
||||
fixed_t P_GetMobjGround(const mobj_t *mobj)
|
||||
{
|
||||
return P_IsObjectFlipped(mobj) ? mobj->ceilingz : mobj->floorz;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,6 +277,11 @@ static void P_NetArchivePlayers(void)
|
|||
|
||||
WRITESINT8(save_p, players[i].glanceDir);
|
||||
|
||||
WRITEUINT8(save_p, players[i].typing_timer);
|
||||
WRITEUINT8(save_p, players[i].typing_duration);
|
||||
|
||||
WRITEUINT8(save_p, players[i].kickstartaccel);
|
||||
|
||||
// respawnvars_t
|
||||
WRITEUINT8(save_p, players[i].respawn.state);
|
||||
WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].respawn.wp));
|
||||
|
|
@ -483,6 +488,11 @@ static void P_NetUnArchivePlayers(void)
|
|||
|
||||
players[i].glanceDir = READSINT8(save_p);
|
||||
|
||||
players[i].typing_timer = READUINT8(save_p);
|
||||
players[i].typing_duration = READUINT8(save_p);
|
||||
|
||||
players[i].kickstartaccel = READUINT8(save_p);
|
||||
|
||||
// respawnvars_t
|
||||
players[i].respawn.state = READUINT8(save_p);
|
||||
players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save_p);
|
||||
|
|
@ -4180,6 +4190,7 @@ static void P_NetArchiveMisc(void)
|
|||
|
||||
WRITEUINT32(save_p, introtime);
|
||||
WRITEUINT32(save_p, starttime);
|
||||
WRITEUINT8(save_p, numbulbs);
|
||||
|
||||
// Is it paused?
|
||||
if (paused)
|
||||
|
|
@ -4314,6 +4325,7 @@ static inline boolean P_NetUnArchiveMisc(void)
|
|||
|
||||
introtime = READUINT32(save_p);
|
||||
starttime = READUINT32(save_p);
|
||||
numbulbs = READUINT8(save_p);
|
||||
|
||||
// Is it paused?
|
||||
if (READUINT8(save_p) == 0x2f)
|
||||
|
|
|
|||
|
|
@ -1261,6 +1261,24 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
break;
|
||||
}
|
||||
|
||||
case 423: // Change Sky
|
||||
{
|
||||
char process[8*3+1];
|
||||
memset(process,0,8*3+1);
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
|
||||
M_Memcpy(process,msd->toptexture,8);
|
||||
if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0')
|
||||
M_Memcpy(process+strlen(process), msd->midtexture, 8);
|
||||
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
|
||||
M_Memcpy(process+strlen(process), msd->bottomtexture, 8);
|
||||
if (!strlen(process))
|
||||
break;
|
||||
sd->text = Z_Malloc(strlen(process)+1, PU_LEVEL, NULL);
|
||||
M_Memcpy(sd->text, process, strlen(process)+1);
|
||||
break;
|
||||
}
|
||||
|
||||
case 9: // Mace parameters
|
||||
case 14: // Bustable block parameters
|
||||
case 15: // Fan particle spawner parameters
|
||||
|
|
@ -3305,6 +3323,9 @@ static boolean P_LoadMapFromFile(void)
|
|||
void P_SetupLevelSky(const char *skytexname, boolean global)
|
||||
{
|
||||
char tex[9];
|
||||
if (!skytexname || !skytexname[0])
|
||||
return;
|
||||
|
||||
strncpy(tex, skytexname, 9);
|
||||
tex[8] = 0;
|
||||
|
||||
|
|
@ -3427,29 +3448,6 @@ static void P_InitLevelSettings(void)
|
|||
players[i].follower = NULL;
|
||||
}
|
||||
|
||||
rainbowstartavailable = false;
|
||||
|
||||
if (p >= 2)
|
||||
rainbowstartavailable = true;
|
||||
|
||||
if (p <= 2)
|
||||
{
|
||||
introtime = 0; // No intro in Record Attack / 1v1
|
||||
}
|
||||
else
|
||||
{
|
||||
introtime = (108) + 5; // 108 for rotation, + 5 for white fade
|
||||
}
|
||||
|
||||
numbulbs = 5;
|
||||
|
||||
if (p > 2)
|
||||
{
|
||||
numbulbs += (p-2);
|
||||
}
|
||||
|
||||
starttime = (introtime + (3*TICRATE)) + ((2*TICRATE) + (numbulbs * bulbtime)); // Start countdown time, + buffer time
|
||||
|
||||
// SRB2Kart: map load variables
|
||||
if (grandprixinfo.gp == true)
|
||||
{
|
||||
|
|
@ -4013,7 +4011,7 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
I_Error("Map %s not found.\n", maplumpname);
|
||||
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette,
|
||||
(encoremode ? W_CheckNumForName(va("%sE", maplumpname)) : LUMPERROR));
|
||||
W_CheckNumForName(va("%s%c", maplumpname, (encoremode ? 'E' : 'T'))));
|
||||
CON_SetupBackColormap();
|
||||
|
||||
// SRB2 determines the sky texture to be used depending on the map header.
|
||||
|
|
@ -4149,21 +4147,6 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
lastmaploaded = gamemap; // HAS to be set after saving!!
|
||||
}
|
||||
|
||||
if (!fromnetsave) // uglier hack
|
||||
{ // to make a newly loaded level start on the second frame.
|
||||
INT32 buf = gametic % TICQUEUE;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1);
|
||||
}
|
||||
P_PreTicker(2);
|
||||
LUAh_MapLoad();
|
||||
}
|
||||
|
||||
// NOW you can try to spawn in the Battle capsules, if there's not enough players for a match
|
||||
K_SpawnBattleCapsules();
|
||||
|
||||
if (grandprixinfo.gp == true)
|
||||
{
|
||||
if (grandprixinfo.initalize == true)
|
||||
|
|
@ -4183,6 +4166,20 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
K_UpdateMatchRaceBots();
|
||||
}
|
||||
|
||||
if (!fromnetsave) // uglier hack
|
||||
{ // to make a newly loaded level start on the second frame.
|
||||
INT32 buf = gametic % TICQUEUE;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1);
|
||||
}
|
||||
P_PreTicker(2);
|
||||
LUAh_MapLoad();
|
||||
}
|
||||
|
||||
K_TimerReset();
|
||||
|
||||
// No render mode, stop here.
|
||||
if (rendermode == render_none)
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -8763,12 +8763,8 @@ void T_Pusher(pusher_t *p)
|
|||
{
|
||||
if (p->slider && thing->player)
|
||||
{
|
||||
pflags_t jumped = (thing->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE));
|
||||
P_ResetPlayer (thing->player);
|
||||
|
||||
if (jumped)
|
||||
thing->player->pflags |= jumped;
|
||||
|
||||
thing->player->pflags |= PF_SLIDING;
|
||||
thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR));
|
||||
|
||||
|
|
|
|||
|
|
@ -705,6 +705,13 @@ void P_Ticker(boolean run)
|
|||
if (demo.playback)
|
||||
G_StoreRewindInfo();
|
||||
|
||||
if (leveltime == 2)
|
||||
{
|
||||
// The values needed to set this properly are not correct at map load,
|
||||
// so we have to do it at the second tick instead...
|
||||
K_TimerInit();
|
||||
}
|
||||
|
||||
// Z_CheckMemCleanup();
|
||||
}
|
||||
|
||||
|
|
|
|||
143
src/p_user.c
143
src/p_user.c
|
|
@ -206,7 +206,7 @@ void P_CalcHeight(player_t *player)
|
|||
|
||||
player->bob = FixedMul(cv_movebob.value, bobmul);
|
||||
|
||||
if (!P_IsObjectOnGround(mo))
|
||||
if (!P_IsObjectOnGround(mo) || player->spectator)
|
||||
{
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
|
|
@ -461,7 +461,7 @@ UINT8 P_FindHighestLap(void)
|
|||
//
|
||||
boolean P_PlayerInPain(player_t *player)
|
||||
{
|
||||
if (player->kartstuff[k_spinouttimer] || player->tumbleBounces > 0)
|
||||
if (player->kartstuff[k_spinouttimer] || (player->tumbleBounces > 0) || (player->pflags & PF_FAULT))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -487,23 +487,29 @@ void P_ResetPlayer(player_t *player)
|
|||
//
|
||||
// Gives rings to the player, and does any special things required.
|
||||
// Call this function when you want to increment the player's health.
|
||||
// Returns the number of rings successfully given (or taken).
|
||||
//
|
||||
|
||||
void P_GivePlayerRings(player_t *player, INT32 num_rings)
|
||||
INT32 P_GivePlayerRings(player_t *player, INT32 num_rings)
|
||||
{
|
||||
INT32 test;
|
||||
|
||||
if (!player->mo)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS)) // No rings in Battle Mode
|
||||
return;
|
||||
return 0;
|
||||
|
||||
test = player->rings + num_rings;
|
||||
if (test > 20) // Caps at 20 rings, sorry!
|
||||
num_rings -= (test-20);
|
||||
else if (test < -20) // Chaotix ring debt!
|
||||
num_rings -= (test+20);
|
||||
|
||||
player->rings += num_rings;
|
||||
//player->totalring += num_rings; // Used for GP lives later
|
||||
//player->totalring += num_rings; // Used for GP lives later -- maybe you might want to move this earlier to discourage ring debt...
|
||||
|
||||
if (player->rings > 20)
|
||||
player->rings = 20; // Caps at 20 rings, sorry!
|
||||
else if (player->rings < -20)
|
||||
player->rings = -20; // Chaotix ring debt!
|
||||
return num_rings;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -2117,11 +2123,7 @@ void P_MovePlayer(player_t *player)
|
|||
|
||||
// Control relinquishing stuff!
|
||||
if (player->powers[pw_nocontrol])
|
||||
{
|
||||
player->pflags |= PF_STASIS;
|
||||
if (!(player->powers[pw_nocontrol] & (1<<15)))
|
||||
player->pflags |= PF_JUMPSTASIS;
|
||||
}
|
||||
|
||||
// note: don't unset stasis here
|
||||
|
||||
|
|
@ -2177,9 +2179,13 @@ void P_MovePlayer(player_t *player)
|
|||
player->drawangle -= ANGLE_22h;
|
||||
player->mo->rollangle = 0;
|
||||
}
|
||||
else if (player->kartstuff[k_spinouttimer] > 0)
|
||||
else if ((player->pflags & PF_FAULT) || (player->kartstuff[k_spinouttimer] > 0))
|
||||
{
|
||||
UINT8 speed = max(1, min(8, player->kartstuff[k_spinouttimer]/8));
|
||||
UINT16 speed = ((player->pflags & PF_FAULT) ? player->powers[pw_nocontrol] : player->kartstuff[k_spinouttimer])/8;
|
||||
if (speed > 8)
|
||||
speed = 8;
|
||||
else if (speed < 1)
|
||||
speed = 1;
|
||||
|
||||
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
|
||||
|
||||
|
|
@ -2190,7 +2196,7 @@ void P_MovePlayer(player_t *player)
|
|||
|
||||
player->mo->rollangle = 0;
|
||||
}
|
||||
else if (player->pflags & PF_FAULT)
|
||||
/*else if (player->pflags & PF_FAULT) -- v1 fault
|
||||
{
|
||||
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
|
||||
|
||||
|
|
@ -2200,7 +2206,7 @@ void P_MovePlayer(player_t *player)
|
|||
player->drawangle -= ANGLE_11hh;
|
||||
|
||||
player->mo->rollangle = 0;
|
||||
}
|
||||
}*/
|
||||
else
|
||||
{
|
||||
K_KartMoveAnimation(player);
|
||||
|
|
@ -2991,7 +2997,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam)
|
|||
if (thiscam->chase && player->mo->health <= 0)
|
||||
return;
|
||||
|
||||
thiscam->chase = true;
|
||||
thiscam->chase = !player->spectator;
|
||||
x = player->mo->x - P_ReturnThrustX(player->mo, thiscam->angle, player->mo->radius);
|
||||
y = player->mo->y - P_ReturnThrustY(player->mo, thiscam->angle, player->mo->radius);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
|
|
@ -3074,6 +3080,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
{
|
||||
// Do not move the camera while in hitlag!
|
||||
// The camera zooming out after you got hit makes it hard to focus on the vibration.
|
||||
// of course, if you're in chase, don't forget the postimage - otherwise encore will flip back
|
||||
if (thiscam->chase)
|
||||
P_CalcChasePostImg(player, thiscam);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -4314,6 +4324,19 @@ void P_PlayerThink(player_t *player)
|
|||
player->kartstuff[k_throwdir] = 0;
|
||||
}
|
||||
|
||||
// Accessibility - kickstart your acceleration
|
||||
if (!(player->pflags & PF_KICKSTARTACCEL))
|
||||
player->kickstartaccel = 0;
|
||||
else if (cmd->buttons & BT_ACCELERATE)
|
||||
{
|
||||
if (!player->exiting && !(player->pflags & PF_ACCELDOWN))
|
||||
player->kickstartaccel = 0;
|
||||
else if (player->kickstartaccel < ACCEL_KICKSTART)
|
||||
player->kickstartaccel++;
|
||||
}
|
||||
else if (player->kickstartaccel < ACCEL_KICKSTART)
|
||||
player->kickstartaccel = 0;
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (player->playerstate == PST_REBORN)
|
||||
I_Error("player %s is in PST_REBORN\n", sizeu1(playeri));
|
||||
|
|
@ -4470,11 +4493,6 @@ void P_PlayerThink(player_t *player)
|
|||
// Allows some turning
|
||||
P_MovePlayer(player);
|
||||
}
|
||||
else if (player->respawn.state == RESPAWNST_MOVE)
|
||||
{
|
||||
angle_t angleChange = player->cmd.turning << TICCMD_REDUCE;
|
||||
P_SetPlayerAngle(player, player->angleturn + angleChange);
|
||||
}
|
||||
}
|
||||
else if (player->mo->reactiontime)
|
||||
{
|
||||
|
|
@ -4496,10 +4514,10 @@ void P_PlayerThink(player_t *player)
|
|||
|
||||
player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame.
|
||||
|
||||
// Unset statis flags after moving.
|
||||
// Unset statis flag after moving.
|
||||
// In other words, if you manually set stasis via code,
|
||||
// it lasts for one tic.
|
||||
player->pflags &= ~PF_FULLSTASIS;
|
||||
player->pflags &= ~PF_STASIS;
|
||||
|
||||
if (player->onconveyor == 1)
|
||||
player->onconveyor = 3;
|
||||
|
|
@ -4545,11 +4563,16 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
#endif
|
||||
|
||||
// check for use
|
||||
if (cmd->buttons & BT_BRAKE)
|
||||
player->pflags |= PF_SPINDOWN;
|
||||
// check for buttons
|
||||
if (cmd->buttons & BT_ACCELERATE)
|
||||
player->pflags |= PF_ACCELDOWN;
|
||||
else
|
||||
player->pflags &= ~PF_SPINDOWN;
|
||||
player->pflags &= ~PF_ACCELDOWN;
|
||||
|
||||
if (cmd->buttons & BT_BRAKE)
|
||||
player->pflags |= PF_BRAKEDOWN;
|
||||
else
|
||||
player->pflags &= ~PF_BRAKEDOWN;
|
||||
|
||||
// Counters, time dependent power ups.
|
||||
// Time Bonus & Ring Bonus count settings
|
||||
|
|
@ -4561,7 +4584,7 @@ void P_PlayerThink(player_t *player)
|
|||
player->powers[pw_flashing]--;
|
||||
}
|
||||
|
||||
if (player->powers[pw_nocontrol] & ((1<<15)-1) && player->powers[pw_nocontrol] < UINT16_MAX)
|
||||
if (player->powers[pw_nocontrol] && player->powers[pw_nocontrol] < UINT16_MAX)
|
||||
{
|
||||
if (!(--player->powers[pw_nocontrol]))
|
||||
player->pflags &= ~PF_FAULT;
|
||||
|
|
@ -4588,6 +4611,64 @@ void P_PlayerThink(player_t *player)
|
|||
player->mo->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
if (cmd->flags & TICCMD_TYPING)
|
||||
{
|
||||
/*
|
||||
typing_duration is slow to start and slow to stop.
|
||||
|
||||
typing_timer counts down a grace period before the player is not
|
||||
actually considered typing anymore.
|
||||
*/
|
||||
if (cmd->flags & TICCMD_KEYSTROKE)
|
||||
{
|
||||
/* speed up if we are typing quickly! */
|
||||
if (player->typing_duration > 0 && player->typing_timer > 12)
|
||||
{
|
||||
if (player->typing_duration < 16)
|
||||
{
|
||||
player->typing_duration = 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* slows down a tiny bit as it approaches the next dot */
|
||||
const UINT8 step = (((player->typing_duration + 15) & ~15) -
|
||||
player->typing_duration) / 2;
|
||||
player->typing_duration += max(step, 4);
|
||||
}
|
||||
}
|
||||
|
||||
player->typing_timer = 15;
|
||||
}
|
||||
else if (player->typing_timer > 0)
|
||||
{
|
||||
player->typing_timer--;
|
||||
}
|
||||
|
||||
/* if we are in the grace period (including currently typing) */
|
||||
if (player->typing_timer + player->typing_duration > 0)
|
||||
{
|
||||
/* always end the cycle on two dots */
|
||||
if (player->typing_timer == 0 &&
|
||||
(player->typing_duration < 16 || player->typing_duration == 40))
|
||||
{
|
||||
player->typing_duration = 0;
|
||||
}
|
||||
else if (player->typing_duration < 63)
|
||||
{
|
||||
player->typing_duration++;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->typing_duration = 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->typing_timer = 0;
|
||||
player->typing_duration = 0;
|
||||
}
|
||||
|
||||
player->pflags &= ~PF_SLIDING;
|
||||
|
||||
K_KartPlayerThink(player, cmd); // SRB2kart
|
||||
|
|
|
|||
14
src/r_data.c
14
src/r_data.c
|
|
@ -287,7 +287,9 @@ static void R_InitColormaps(void)
|
|||
// Load in the light tables
|
||||
lump = W_GetNumForName("COLORMAP");
|
||||
len = W_LumpLength(lump);
|
||||
colormaps = Z_MallocAlign(len * 2, PU_STATIC, NULL, 8); // * 2 for encore
|
||||
if (len < COLORMAP_SIZE*2) // accomodate encore mode later
|
||||
len = COLORMAP_SIZE*2;
|
||||
colormaps = Z_MallocAlign(len, PU_STATIC, NULL, 8);
|
||||
W_ReadLump(lump, colormaps);
|
||||
// no need to init encoremap at this stage
|
||||
|
||||
|
|
@ -330,9 +332,9 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
|
|||
encoremap = Z_MallocAlign(256 + 10, PU_LEVEL, NULL, 8);
|
||||
W_ReadLump(newencoremap, encoremap);
|
||||
colormap_p = colormap_p2 = colormaps;
|
||||
colormap_p += (256 * 32);
|
||||
colormap_p += COLORMAP_REMAPOFFSET;
|
||||
|
||||
for (p = 0; p < 32; p++)
|
||||
for (p = 0; p < LIGHTLEVELS; p++)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
|
|
@ -731,12 +733,12 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
|
|||
|
||||
// Now allocate memory for the actual colormap array itself!
|
||||
// aligned on 8 bit for asm code
|
||||
colormap_p = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8);
|
||||
colormap_p = Z_MallocAlign((COLORMAP_SIZE * (encoremap ? 2 : 1)) + 10, PU_LEVEL, NULL, 8);
|
||||
lighttable = (UINT8 *)colormap_p;
|
||||
|
||||
// Calculate the palette index for each palette index, for each light level
|
||||
// (as well as the two unused colormap lines we inherited from Doom)
|
||||
for (p = 0; p < 32; p++)
|
||||
for (p = 0; p < LIGHTLEVELS; p++)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
|
|
@ -776,7 +778,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
|
|||
{
|
||||
lighttable_t *colormap_p2 = lighttable;
|
||||
|
||||
for (p = 0; p < 32; p++)
|
||||
for (p = 0; p < LIGHTLEVELS; p++)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1698,7 +1698,7 @@ void R_DrawColumnShadowed_8(void)
|
|||
{
|
||||
dc_colormap = dc_lightlist[i].rcolormap;
|
||||
if (encoremap)
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
if (solid && dc_yl < bheight)
|
||||
dc_yl = bheight;
|
||||
continue;
|
||||
|
|
@ -1716,7 +1716,7 @@ void R_DrawColumnShadowed_8(void)
|
|||
|
||||
dc_colormap = dc_lightlist[i].rcolormap;
|
||||
if (encoremap)
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
dc_yh = realyh;
|
||||
if (dc_yl <= realyh)
|
||||
|
|
|
|||
|
|
@ -1191,9 +1191,7 @@ void R_SetupFrame(player_t *player)
|
|||
if (i > r_splitscreen)
|
||||
return; // shouldn't be possible, but just in case
|
||||
|
||||
if (player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode)
|
||||
chasecam = true; // force chasecam on
|
||||
else if (player->spectator) // no spectator chasecam
|
||||
if (player->spectator) // no spectator chasecam
|
||||
chasecam = false; // force chasecam off
|
||||
|
||||
if (chasecam && !thiscam->chase)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ extern size_t validcount, linecount, loopcount, framecount;
|
|||
|
||||
// Lighting constants.
|
||||
// Now with 32 levels.
|
||||
#define LIGHTLEVELS 32
|
||||
// LIGHTLEVELS is now defined in r_state.h
|
||||
#define LIGHTSEGSHIFT 3
|
||||
|
||||
#define MAXLIGHTSCALE 48
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
|
|||
ds_colormap = planezlight[pindex];
|
||||
|
||||
if (encoremap && !currentplane->noencore)
|
||||
ds_colormap += (256*32);
|
||||
ds_colormap += COLORMAP_REMAPOFFSET;
|
||||
|
||||
if (currentplane->extra_colormap)
|
||||
ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps);
|
||||
|
|
@ -644,6 +644,8 @@ static void R_DrawSkyPlane(visplane_t *pl)
|
|||
// Because of this hack, sky is not affected
|
||||
// by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant).
|
||||
dc_colormap = colormaps;
|
||||
if (encoremap)
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_texturemid = skytexturemid;
|
||||
dc_texheight = textureheight[skytexture]
|
||||
>>FRACBITS;
|
||||
|
|
|
|||
16
src/r_segs.c
16
src/r_segs.c
|
|
@ -203,7 +203,7 @@ static void R_DrawWallSplats(void)
|
|||
pindex = MAXLIGHTSCALE - 1;
|
||||
dc_colormap = walllights[pindex];
|
||||
if (encoremap && !(seg->linedef->flags & ML_TFERLINE))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
|
||||
if (frontsector->extra_colormap)
|
||||
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
|
@ -578,7 +578,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
{
|
||||
dc_colormap = rlight->rcolormap;
|
||||
if (encoremap && !(ldef->flags & ML_TFERLINE))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -599,7 +599,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
windowtop = windowbottom + 1;
|
||||
dc_colormap = rlight->rcolormap;
|
||||
if (encoremap && !(ldef->flags & ML_TFERLINE))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
windowbottom = realbot;
|
||||
if (windowtop < windowbottom)
|
||||
|
|
@ -617,7 +617,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
|
||||
dc_colormap = walllights[pindex];
|
||||
if (encoremap && !(ldef->flags & ML_TFERLINE))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
|
||||
if (frontsector->extra_colormap)
|
||||
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
|
@ -1163,7 +1163,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
{
|
||||
dc_colormap = rlight->rcolormap;
|
||||
if (encoremap && !(curline->linedef->flags & ML_TFERLINE))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
if (solid && windowtop < bheight)
|
||||
windowtop = bheight;
|
||||
|
|
@ -1195,7 +1195,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
{
|
||||
dc_colormap = rlight->rcolormap;
|
||||
if (encoremap && !(curline->linedef->flags & ML_TFERLINE))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
}
|
||||
windowbottom = sprbotscreen;
|
||||
|
|
@ -1216,7 +1216,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
dc_colormap = walllights[pindex];
|
||||
|
||||
if (encoremap && !(curline->linedef->flags & ML_TFERLINE))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
|
||||
if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap)
|
||||
dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
|
@ -1476,7 +1476,7 @@ static void R_RenderSegLoop (void)
|
|||
|
||||
dc_colormap = walllights[pindex];
|
||||
if (encoremap && !(curline->linedef->flags & ML_TFERLINE))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_x = rw_x;
|
||||
dc_iscale = 0xffffffffu / (unsigned)rw_scale;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ extern UINT8 *encoremap;
|
|||
extern UINT8 invertmap[256];
|
||||
#endif
|
||||
|
||||
#define LIGHTLEVELS 32
|
||||
#define COLORMAP_SIZE (256*LIGHTLEVELS)
|
||||
#define COLORMAP_REMAPOFFSET COLORMAP_SIZE
|
||||
|
||||
// Boom colormaps.
|
||||
extern extracolormap_t *extra_colormaps;
|
||||
|
||||
|
|
|
|||
|
|
@ -863,7 +863,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
dc_colormap = colormaps;
|
||||
|
||||
if (encoremap && !vis->mobj->color && !(vis->mobj->flags & MF_DONTENCOREMAP))
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
|
||||
dc_texturemid = vis->texturemid;
|
||||
dc_texheight = 0;
|
||||
|
|
@ -993,7 +993,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
|
||||
dc_colormap = colormaps;
|
||||
if (encoremap)
|
||||
dc_colormap += (256*32);
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
|
||||
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
|
||||
dc_texturemid = vis->texturemid;
|
||||
|
|
@ -1404,7 +1404,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t scalestep;
|
||||
fixed_t offset, offset2;
|
||||
|
||||
fixed_t basetx; // drop shadows
|
||||
fixed_t basetx, basetz; // drop shadows
|
||||
|
||||
boolean papersprite = !!(thing->frame & FF_PAPERSPRITE);
|
||||
fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0;
|
||||
|
|
@ -1445,7 +1445,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
tr_x = thingxpos - viewx;
|
||||
tr_y = thingypos - viewy;
|
||||
|
||||
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
|
||||
basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance
|
||||
|
||||
// thing is behind view plane?
|
||||
if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
|
||||
|
|
@ -1911,7 +1911,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
R_SplitSprite(vis);
|
||||
|
||||
if (oldthing->shadowscale && cv_shadow.value)
|
||||
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz);
|
||||
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz);
|
||||
|
||||
// Debug
|
||||
++objectsdrawn;
|
||||
|
|
|
|||
|
|
@ -1454,7 +1454,7 @@ void V_DrawCustomFadeScreen(const char *lump, UINT8 strength)
|
|||
|
||||
if (lumpnum != LUMPERROR)
|
||||
{
|
||||
clm = Z_MallocAlign((256 * 32), PU_STATIC, NULL, 8);
|
||||
clm = Z_MallocAlign(COLORMAP_SIZE, PU_STATIC, NULL, 8);
|
||||
W_ReadLump(lumpnum, clm);
|
||||
|
||||
if (clm != NULL)
|
||||
|
|
@ -1505,7 +1505,7 @@ void V_EncoreInvertScreen(void)
|
|||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft && rendermode != render_none)
|
||||
{
|
||||
//HWR_EncoreInvertScreen();
|
||||
HWR_EncoreInvertScreen();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue