Merge branch 'master' into bots-brake-earlier

This commit is contained in:
Sally Coolatta 2021-02-26 00:29:48 -05:00
commit a4b673705a
46 changed files with 998 additions and 345 deletions

View file

@ -233,7 +233,10 @@ void D_ProcessEvents(void)
#endif
if (eaten)
{
hu_keystrokes = true;
continue; // ate the event
}
G_Responder(ev);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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)

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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];

View file

@ -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;

View file

@ -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

View file

@ -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)
{

View file

@ -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)

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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--;
}
}

View file

@ -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();

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -23,6 +23,7 @@
typedef struct waypoint_s
{
mobj_t *mobj;
boolean onaline;
struct waypoint_s **nextwaypoints;
struct waypoint_s **prevwaypoints;
UINT32 *nextwaypointdistances;

View file

@ -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},

View file

@ -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);

View file

@ -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++);
}
}

View file

@ -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__

View file

@ -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.

View file

@ -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);

View file

@ -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;
}

View file

@ -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)

View file

@ -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;

View file

@ -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));

View file

@ -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();
}

View file

@ -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

View file

@ -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++)
{

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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