mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart.git into votefree
This commit is contained in:
commit
2df53dd5a5
29 changed files with 825 additions and 155 deletions
|
|
@ -113,3 +113,4 @@ k_grandprix.c
|
||||||
k_hud.c
|
k_hud.c
|
||||||
k_terrain.c
|
k_terrain.c
|
||||||
k_brightmap.c
|
k_brightmap.c
|
||||||
|
k_director.c
|
||||||
|
|
@ -382,7 +382,7 @@ consvar_t cv_kartencore = CVAR_INIT ("kartencore", "Auto", CV_NETVAR|CV_CALL|CV_
|
||||||
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
|
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
|
||||||
consvar_t cv_kartvoterulechanges = CVAR_INIT ("kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL);
|
consvar_t cv_kartvoterulechanges = CVAR_INIT ("kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL);
|
||||||
static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}};
|
static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}};
|
||||||
consvar_t cv_kartspeedometer = CVAR_INIT ("kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display
|
consvar_t cv_kartspeedometer = CVAR_INIT ("kartdisplayspeed", "Percentage", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display
|
||||||
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
|
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
|
||||||
consvar_t cv_kartvoices = CVAR_INIT ("kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL);
|
consvar_t cv_kartvoices = CVAR_INIT ("kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL);
|
||||||
|
|
||||||
|
|
@ -423,7 +423,7 @@ consvar_t cv_kartallowgiveitem = CVAR_INIT ("kartallowgiveitem",
|
||||||
#endif
|
#endif
|
||||||
CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_YesNo, NULL
|
CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_YesNo, NULL
|
||||||
);
|
);
|
||||||
consvar_t cv_kartdebugshrink = CVAR_INIT ("kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
|
||||||
consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
|
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
|
||||||
|
|
@ -433,6 +433,7 @@ consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_N
|
||||||
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
|
consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
|
|
||||||
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL);
|
consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL);
|
||||||
|
|
@ -509,6 +510,8 @@ static CV_PossibleValue_t perfstats_cons_t[] = {
|
||||||
{0, "Off"}, {1, "Rendering"}, {2, "Logic"}, {3, "ThinkFrame"}, {0, NULL}};
|
{0, "Off"}, {1, "Rendering"}, {2, "Logic"}, {3, "ThinkFrame"}, {0, NULL}};
|
||||||
consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", 0, perfstats_cons_t, NULL);
|
consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", 0, perfstats_cons_t, NULL);
|
||||||
|
|
||||||
|
consvar_t cv_director = CVAR_INIT ("director", "Off", 0, CV_OnOff, NULL);
|
||||||
|
|
||||||
char timedemo_name[256];
|
char timedemo_name[256];
|
||||||
boolean timedemo_csv;
|
boolean timedemo_csv;
|
||||||
char timedemo_csv_id[256];
|
char timedemo_csv_id[256];
|
||||||
|
|
@ -741,6 +744,8 @@ void D_RegisterServerCommands(void)
|
||||||
CV_RegisterVar(&cv_showping);
|
CV_RegisterVar(&cv_showping);
|
||||||
CV_RegisterVar(&cv_showviewpointtext);
|
CV_RegisterVar(&cv_showviewpointtext);
|
||||||
|
|
||||||
|
CV_RegisterVar(&cv_director);
|
||||||
|
|
||||||
CV_RegisterVar(&cv_dummyconsvar);
|
CV_RegisterVar(&cv_dummyconsvar);
|
||||||
|
|
||||||
#ifdef USE_STUN
|
#ifdef USE_STUN
|
||||||
|
|
@ -935,6 +940,7 @@ void D_RegisterClientCommands(void)
|
||||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
{
|
{
|
||||||
CV_RegisterVar(&cv_kickstartaccel[i]);
|
CV_RegisterVar(&cv_kickstartaccel[i]);
|
||||||
|
CV_RegisterVar(&cv_shrinkme[i]);
|
||||||
CV_RegisterVar(&cv_turnaxis[i]);
|
CV_RegisterVar(&cv_turnaxis[i]);
|
||||||
CV_RegisterVar(&cv_moveaxis[i]);
|
CV_RegisterVar(&cv_moveaxis[i]);
|
||||||
CV_RegisterVar(&cv_brakeaxis[i]);
|
CV_RegisterVar(&cv_brakeaxis[i]);
|
||||||
|
|
@ -1636,10 +1642,13 @@ void SendWeaponPref(UINT8 n)
|
||||||
UINT8 buf[1];
|
UINT8 buf[1];
|
||||||
|
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
// Player option cvars that need to be synched go HERE
|
|
||||||
if (cv_kickstartaccel[n].value)
|
if (cv_kickstartaccel[n].value)
|
||||||
buf[0] |= 1;
|
buf[0] |= 1;
|
||||||
|
|
||||||
|
if (cv_shrinkme[n].value)
|
||||||
|
buf[0] |= 2;
|
||||||
|
|
||||||
SendNetXCmdForPlayer(n, XD_WEAPONPREF, buf, 1);
|
SendNetXCmdForPlayer(n, XD_WEAPONPREF, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1647,11 +1656,22 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
|
||||||
{
|
{
|
||||||
UINT8 prefs = READUINT8(*cp);
|
UINT8 prefs = READUINT8(*cp);
|
||||||
|
|
||||||
// Player option cvars that need to be synched go HERE
|
players[playernum].pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME);
|
||||||
players[playernum].pflags &= ~(PF_KICKSTARTACCEL);
|
|
||||||
if (prefs & 1)
|
if (prefs & 1)
|
||||||
players[playernum].pflags |= PF_KICKSTARTACCEL;
|
players[playernum].pflags |= PF_KICKSTARTACCEL;
|
||||||
|
|
||||||
|
if (prefs & 2)
|
||||||
|
players[playernum].pflags |= PF_SHRINKME;
|
||||||
|
|
||||||
|
if (leveltime < 2)
|
||||||
|
{
|
||||||
|
// BAD HACK: No other place I tried to slot this in
|
||||||
|
// made it work for the host when they initally host,
|
||||||
|
// so this will have to do.
|
||||||
|
K_UpdateShrinkCheat(&players[playernum]);
|
||||||
|
}
|
||||||
|
|
||||||
// SEE ALSO g_demo.c
|
// SEE ALSO g_demo.c
|
||||||
demo_extradata[playernum] |= DXD_WEAPONPREF;
|
demo_extradata[playernum] |= DXD_WEAPONPREF;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,8 @@ extern consvar_t cv_kartusepwrlv;
|
||||||
|
|
||||||
extern consvar_t cv_votetime;
|
extern consvar_t cv_votetime;
|
||||||
|
|
||||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize;
|
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector;
|
||||||
extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;
|
extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;
|
||||||
|
|
||||||
extern consvar_t cv_itemfinder;
|
extern consvar_t cv_itemfinder;
|
||||||
|
|
@ -113,6 +113,8 @@ extern consvar_t cv_sleep;
|
||||||
|
|
||||||
extern consvar_t cv_perfstats;
|
extern consvar_t cv_perfstats;
|
||||||
|
|
||||||
|
extern consvar_t cv_director;
|
||||||
|
|
||||||
extern char timedemo_name[256];
|
extern char timedemo_name[256];
|
||||||
extern boolean timedemo_csv;
|
extern boolean timedemo_csv;
|
||||||
extern char timedemo_csv_id[256];
|
extern char timedemo_csv_id[256];
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,10 @@ typedef enum
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
// True if button down last tic.
|
// True if button down last tic.
|
||||||
PF_ATTACKDOWN = 1,
|
PF_ATTACKDOWN = 1,
|
||||||
PF_ACCELDOWN = 1<<1,
|
PF_ACCELDOWN = 1<<1,
|
||||||
PF_BRAKEDOWN = 1<<2,
|
PF_BRAKEDOWN = 1<<2,
|
||||||
PF_LOOKDOWN = 1<<3,
|
PF_LOOKDOWN = 1<<3,
|
||||||
|
|
||||||
// Accessibility and cheats
|
// Accessibility and cheats
|
||||||
PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode?
|
PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode?
|
||||||
|
|
@ -99,6 +99,9 @@ typedef enum
|
||||||
PF_HITFINISHLINE = 1<<26, // Already hit the finish line this tic
|
PF_HITFINISHLINE = 1<<26, // Already hit the finish line this tic
|
||||||
PF_WRONGWAY = 1<<27, // Moving the wrong way with respect to waypoints?
|
PF_WRONGWAY = 1<<27, // Moving the wrong way with respect to waypoints?
|
||||||
|
|
||||||
|
PF_SHRINKME = 1<<28, // "Shrink me" cheat preference
|
||||||
|
PF_SHRINKACTIVE = 1<<29, // "Shrink me" cheat is in effect. (Can't be disabled mid-race)
|
||||||
|
|
||||||
// up to 1<<31 is free
|
// up to 1<<31 is free
|
||||||
} pflags_t;
|
} pflags_t;
|
||||||
|
|
||||||
|
|
@ -260,6 +263,10 @@ typedef enum
|
||||||
// for kickstartaccel
|
// for kickstartaccel
|
||||||
#define ACCEL_KICKSTART 35
|
#define ACCEL_KICKSTART 35
|
||||||
|
|
||||||
|
#define ITEMSCALE_NORMAL 0
|
||||||
|
#define ITEMSCALE_GROW 1
|
||||||
|
#define ITEMSCALE_SHRINK 2
|
||||||
|
|
||||||
// player_t struct for all respawn variables
|
// player_t struct for all respawn variables
|
||||||
typedef struct respawnvars_s
|
typedef struct respawnvars_s
|
||||||
{
|
{
|
||||||
|
|
@ -436,6 +443,7 @@ typedef struct player_s
|
||||||
SINT8 itemtype; // KITEM_ constant for item number
|
SINT8 itemtype; // KITEM_ constant for item number
|
||||||
UINT8 itemamount; // Amount of said item
|
UINT8 itemamount; // Amount of said item
|
||||||
SINT8 throwdir; // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
|
SINT8 throwdir; // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
|
||||||
|
UINT8 itemscale; // Item scale value, from when an item was taken out. (0 for normal, 1 for grow, 2 for shrink.)
|
||||||
|
|
||||||
UINT8 sadtimer; // How long you've been sad
|
UINT8 sadtimer; // How long you've been sad
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5809,6 +5809,7 @@ const char *const MOBJFLAG_LIST[] = {
|
||||||
"DONTENCOREMAP",
|
"DONTENCOREMAP",
|
||||||
"PICKUPFROMBELOW",
|
"PICKUPFROMBELOW",
|
||||||
"NOSQUISH",
|
"NOSQUISH",
|
||||||
|
"NOHITLAGFORME",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -5912,6 +5913,10 @@ const char *const PLAYERFLAG_LIST[] = {
|
||||||
|
|
||||||
"HITFINISHLINE", // Already hit the finish line this tic
|
"HITFINISHLINE", // Already hit the finish line this tic
|
||||||
"WRONGWAY", // Moving the wrong way with respect to waypoints?
|
"WRONGWAY", // Moving the wrong way with respect to waypoints?
|
||||||
|
|
||||||
|
"SHRINKME",
|
||||||
|
"SHRINKACTIVE",
|
||||||
|
|
||||||
NULL // stop loop here.
|
NULL // stop loop here.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -6555,6 +6560,7 @@ struct int_const_s const INT_CONST[] = {
|
||||||
//// Masks
|
//// Masks
|
||||||
{"DMG_STEAL",DMG_CANTHURTSELF},
|
{"DMG_STEAL",DMG_CANTHURTSELF},
|
||||||
{"DMG_CANTHURTSELF",DMG_CANTHURTSELF},
|
{"DMG_CANTHURTSELF",DMG_CANTHURTSELF},
|
||||||
|
{"DMG_WOMBO", DMG_WOMBO},
|
||||||
{"DMG_DEATHMASK",DMG_DEATHMASK},
|
{"DMG_DEATHMASK",DMG_DEATHMASK},
|
||||||
{"DMG_TYPEMASK",DMG_TYPEMASK},
|
{"DMG_TYPEMASK",DMG_TYPEMASK},
|
||||||
|
|
||||||
|
|
|
||||||
60
src/g_demo.c
60
src/g_demo.c
|
|
@ -122,8 +122,9 @@ demoghost *ghosts = NULL;
|
||||||
#define DF_ENCORE 0x40
|
#define DF_ENCORE 0x40
|
||||||
#define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode!
|
#define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode!
|
||||||
|
|
||||||
#define DEMO_SPECTATOR 0x40
|
#define DEMO_SPECTATOR 0x01
|
||||||
#define DEMO_KICKSTART 0x20
|
#define DEMO_KICKSTART 0x02
|
||||||
|
#define DEMO_SHRINKME 0x04
|
||||||
|
|
||||||
// For demos
|
// For demos
|
||||||
#define ZT_FWD 0x01
|
#define ZT_FWD 0x01
|
||||||
|
|
@ -351,9 +352,20 @@ void G_ReadDemoExtraData(void)
|
||||||
if (extradata & DXD_WEAPONPREF)
|
if (extradata & DXD_WEAPONPREF)
|
||||||
{
|
{
|
||||||
i = READUINT8(demo_p);
|
i = READUINT8(demo_p);
|
||||||
players[p].pflags &= ~(PF_KICKSTARTACCEL);
|
players[p].pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME);
|
||||||
if (i & 1)
|
if (i & 1)
|
||||||
players[p].pflags |= PF_KICKSTARTACCEL;
|
players[p].pflags |= PF_KICKSTARTACCEL;
|
||||||
|
if (i & 2)
|
||||||
|
players[p].pflags |= PF_SHRINKME;
|
||||||
|
|
||||||
|
if (leveltime < 2)
|
||||||
|
{
|
||||||
|
// BAD HACK: No other place I tried to slot this in
|
||||||
|
// made it work for the host when they initally host,
|
||||||
|
// so this will have to do.
|
||||||
|
K_UpdateShrinkCheat(&players[p]);
|
||||||
|
}
|
||||||
|
|
||||||
//CONS_Printf("weaponpref is %d for player %d\n", i, p);
|
//CONS_Printf("weaponpref is %d for player %d\n", i, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -466,6 +478,8 @@ void G_WriteDemoExtraData(void)
|
||||||
UINT8 prefs = 0;
|
UINT8 prefs = 0;
|
||||||
if (players[i].pflags & PF_KICKSTARTACCEL)
|
if (players[i].pflags & PF_KICKSTARTACCEL)
|
||||||
prefs |= 1;
|
prefs |= 1;
|
||||||
|
if (players[i].pflags & PF_SHRINKME)
|
||||||
|
prefs |= 2;
|
||||||
WRITEUINT8(demo_p, prefs);
|
WRITEUINT8(demo_p, prefs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2015,12 +2029,15 @@ void G_BeginRecording(void)
|
||||||
for (p = 0; p < MAXPLAYERS; p++) {
|
for (p = 0; p < MAXPLAYERS; p++) {
|
||||||
if (playeringame[p]) {
|
if (playeringame[p]) {
|
||||||
player = &players[p];
|
player = &players[p];
|
||||||
|
WRITEUINT8(demo_p, p);
|
||||||
|
|
||||||
i = p;
|
i = 0;
|
||||||
if (player->pflags & PF_KICKSTARTACCEL)
|
|
||||||
i |= DEMO_KICKSTART;
|
|
||||||
if (player->spectator)
|
if (player->spectator)
|
||||||
i |= DEMO_SPECTATOR;
|
i |= DEMO_SPECTATOR;
|
||||||
|
if (player->pflags & PF_KICKSTARTACCEL)
|
||||||
|
i |= DEMO_KICKSTART;
|
||||||
|
if (player->pflags & PF_SHRINKME)
|
||||||
|
i |= DEMO_SHRINKME;
|
||||||
WRITEUINT8(demo_p, i);
|
WRITEUINT8(demo_p, i);
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
|
|
@ -2672,7 +2689,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
UINT32 randseed;
|
UINT32 randseed;
|
||||||
char msg[1024];
|
char msg[1024];
|
||||||
|
|
||||||
boolean spectator, kickstart;
|
boolean spectator;
|
||||||
UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0;
|
UINT8 slots[MAXPLAYERS], kartspeed[MAXPLAYERS], kartweight[MAXPLAYERS], numslots = 0;
|
||||||
|
|
||||||
#if defined(SKIPERRORS) && !defined(DEVELOP)
|
#if defined(SKIPERRORS) && !defined(DEVELOP)
|
||||||
|
|
@ -2943,10 +2960,12 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
|
|
||||||
while (p != 0xFF)
|
while (p != 0xFF)
|
||||||
{
|
{
|
||||||
if ((spectator = !!(p & DEMO_SPECTATOR)))
|
UINT8 flags = READUINT8(demo_p);
|
||||||
{
|
|
||||||
p &= ~DEMO_SPECTATOR;
|
|
||||||
|
|
||||||
|
spectator = !!(flags & DEMO_SPECTATOR);
|
||||||
|
|
||||||
|
if (spectator == true)
|
||||||
|
{
|
||||||
if (modeattacking)
|
if (modeattacking)
|
||||||
{
|
{
|
||||||
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
|
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
|
||||||
|
|
@ -2960,10 +2979,8 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((kickstart = (p & DEMO_KICKSTART)))
|
slots[numslots] = p;
|
||||||
p &= ~DEMO_KICKSTART;
|
numslots++;
|
||||||
|
|
||||||
slots[numslots] = p; numslots++;
|
|
||||||
|
|
||||||
if (modeattacking && numslots > 1)
|
if (modeattacking && numslots > 1)
|
||||||
{
|
{
|
||||||
|
|
@ -2982,11 +2999,19 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
|
|
||||||
playeringame[p] = true;
|
playeringame[p] = true;
|
||||||
players[p].spectator = spectator;
|
players[p].spectator = spectator;
|
||||||
if (kickstart)
|
|
||||||
|
if (flags & DEMO_KICKSTART)
|
||||||
players[p].pflags |= PF_KICKSTARTACCEL;
|
players[p].pflags |= PF_KICKSTARTACCEL;
|
||||||
else
|
else
|
||||||
players[p].pflags &= ~PF_KICKSTARTACCEL;
|
players[p].pflags &= ~PF_KICKSTARTACCEL;
|
||||||
|
|
||||||
|
if (flags & DEMO_SHRINKME)
|
||||||
|
players[p].pflags |= PF_SHRINKME;
|
||||||
|
else
|
||||||
|
players[p].pflags &= ~PF_SHRINKME;
|
||||||
|
|
||||||
|
K_UpdateShrinkCheat(&players[p]);
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
M_Memcpy(player_names[p],demo_p,16);
|
M_Memcpy(player_names[p],demo_p,16);
|
||||||
demo_p += 16;
|
demo_p += 16;
|
||||||
|
|
@ -3245,7 +3270,10 @@ void G_AddGhost(char *defdemoname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((READUINT8(p) & ~DEMO_KICKSTART) != 0)
|
p++; // player number - doesn't really need to be checked, TODO maybe support adding multiple players' ghosts at once
|
||||||
|
|
||||||
|
// any invalidating flags?
|
||||||
|
if ((READUINT8(p) & (DEMO_SPECTATOR)) != 0)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
||||||
Z_Free(pdemoname);
|
Z_Free(pdemoname);
|
||||||
|
|
|
||||||
34
src/g_game.c
34
src/g_game.c
|
|
@ -342,10 +342,10 @@ INT16 prevmap, nextmap;
|
||||||
|
|
||||||
static UINT8 *savebuffer;
|
static UINT8 *savebuffer;
|
||||||
|
|
||||||
static void kickstartaccel_OnChange(void);
|
static void weaponPrefChange(void);
|
||||||
static void kickstartaccel2_OnChange(void);
|
static void weaponPrefChange2(void);
|
||||||
static void kickstartaccel3_OnChange(void);
|
static void weaponPrefChange3(void);
|
||||||
static void kickstartaccel4_OnChange(void);
|
static void weaponPrefChange4(void);
|
||||||
|
|
||||||
static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
|
static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
|
||||||
{1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"},
|
{1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"},
|
||||||
|
|
@ -406,10 +406,17 @@ 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_resume = CVAR_INIT ("resume", "Yes", CV_SAVE, CV_YesNo, NULL);
|
||||||
|
|
||||||
consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS] = {
|
consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS] = {
|
||||||
CVAR_INIT ("kickstartaccel", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel_OnChange),
|
CVAR_INIT ("kickstartaccel", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange),
|
||||||
CVAR_INIT ("kickstartaccel2", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel2_OnChange),
|
CVAR_INIT ("kickstartaccel2", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange2),
|
||||||
CVAR_INIT ("kickstartaccel3", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel3_OnChange),
|
CVAR_INIT ("kickstartaccel3", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange3),
|
||||||
CVAR_INIT ("kickstartaccel4", "Off", CV_SAVE|CV_CALL, CV_OnOff, kickstartaccel4_OnChange)
|
CVAR_INIT ("kickstartaccel4", "Off", CV_SAVE|CV_CALL, CV_OnOff, weaponPrefChange4)
|
||||||
|
};
|
||||||
|
|
||||||
|
consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS] = {
|
||||||
|
CVAR_INIT ("shrinkme", "Off", CV_CALL, CV_OnOff, weaponPrefChange),
|
||||||
|
CVAR_INIT ("shrinkme2", "Off", CV_CALL, CV_OnOff, weaponPrefChange2),
|
||||||
|
CVAR_INIT ("shrinkme3", "Off", CV_CALL, CV_OnOff, weaponPrefChange3),
|
||||||
|
CVAR_INIT ("shrinkme4", "Off", CV_CALL, CV_OnOff, weaponPrefChange4)
|
||||||
};
|
};
|
||||||
|
|
||||||
consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS] = {
|
consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS] = {
|
||||||
|
|
@ -1183,22 +1190,22 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n)
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kickstartaccel_OnChange(void)
|
static void weaponPrefChange(void)
|
||||||
{
|
{
|
||||||
SendWeaponPref(0);
|
SendWeaponPref(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kickstartaccel2_OnChange(void)
|
static void weaponPrefChange2(void)
|
||||||
{
|
{
|
||||||
SendWeaponPref(1);
|
SendWeaponPref(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kickstartaccel3_OnChange(void)
|
static void weaponPrefChange3(void)
|
||||||
{
|
{
|
||||||
SendWeaponPref(2);
|
SendWeaponPref(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kickstartaccel4_OnChange(void)
|
static void weaponPrefChange4(void)
|
||||||
{
|
{
|
||||||
SendWeaponPref(3);
|
SendWeaponPref(3);
|
||||||
}
|
}
|
||||||
|
|
@ -2164,7 +2171,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
botdiffincrease = players[player].botvars.diffincrease;
|
botdiffincrease = players[player].botvars.diffincrease;
|
||||||
botrival = players[player].botvars.rival;
|
botrival = players[player].botvars.rival;
|
||||||
|
|
||||||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL));
|
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE));
|
||||||
|
|
||||||
// SRB2kart
|
// SRB2kart
|
||||||
if (betweenmaps || leveltime < introtime)
|
if (betweenmaps || leveltime < introtime)
|
||||||
|
|
@ -2235,7 +2242,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
if (!(netgame || multiplayer))
|
if (!(netgame || multiplayer))
|
||||||
pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP));
|
pflags |= (players[player].pflags & (PF_GODMODE|PF_NOCLIP));
|
||||||
|
|
||||||
|
|
||||||
// Obliterate follower from existence
|
// Obliterate follower from existence
|
||||||
P_SetTarget(&players[player].follower, NULL);
|
P_SetTarget(&players[player].follower, NULL);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ extern consvar_t cv_pauseifunfocused;
|
||||||
extern consvar_t cv_invertmouse;
|
extern consvar_t cv_invertmouse;
|
||||||
|
|
||||||
extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS];
|
extern consvar_t cv_kickstartaccel[MAXSPLITSCREENPLAYERS];
|
||||||
|
extern consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS];
|
||||||
|
|
||||||
extern consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS];
|
extern consvar_t cv_turnaxis[MAXSPLITSCREENPLAYERS];
|
||||||
extern consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS];
|
extern consvar_t cv_moveaxis[MAXSPLITSCREENPLAYERS];
|
||||||
extern consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS];
|
extern consvar_t cv_brakeaxis[MAXSPLITSCREENPLAYERS];
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,18 @@ boolean gl_shadersavailable = true;
|
||||||
// Lighting
|
// Lighting
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
|
boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel)
|
||||||
|
{
|
||||||
|
if (R_ThingIsFullBright(thing))
|
||||||
|
*lightlevel = 255;
|
||||||
|
else if (R_ThingIsFullDark(thing))
|
||||||
|
*lightlevel = 0;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap)
|
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap)
|
||||||
{
|
{
|
||||||
RGBA_t poly_color, tint_color, fade_color;
|
RGBA_t poly_color, tint_color, fade_color;
|
||||||
|
|
@ -3795,7 +3807,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||||
patch_t *gpatch;
|
patch_t *gpatch;
|
||||||
FSurfaceInfo Surf;
|
FSurfaceInfo Surf;
|
||||||
extracolormap_t *colormap = NULL;
|
extracolormap_t *colormap = NULL;
|
||||||
FUINT lightlevel;
|
INT32 lightlevel;
|
||||||
boolean lightset = true;
|
boolean lightset = true;
|
||||||
FBITFIELD blend = 0;
|
FBITFIELD blend = 0;
|
||||||
FBITFIELD occlusion;
|
FBITFIELD occlusion;
|
||||||
|
|
@ -3925,18 +3937,13 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||||
|
|
||||||
// Start with the lightlevel and colormap from the top of the sprite
|
// Start with the lightlevel and colormap from the top of the sprite
|
||||||
lightlevel = *list[sector->numlights - 1].lightlevel;
|
lightlevel = *list[sector->numlights - 1].lightlevel;
|
||||||
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||||
colormap = *list[sector->numlights - 1].extra_colormap;
|
colormap = *list[sector->numlights - 1].extra_colormap;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
temp = FLOAT_TO_FIXED(realtop);
|
temp = FLOAT_TO_FIXED(realtop);
|
||||||
|
|
||||||
if (R_ThingIsFullBright(spr->mobj))
|
lightset = HWR_OverrideObjectLightLevel(spr->mobj, &lightlevel);
|
||||||
lightlevel = 255;
|
|
||||||
else if (R_ThingIsFullDark(spr->mobj))
|
|
||||||
lightlevel = 0;
|
|
||||||
else
|
|
||||||
lightset = false;
|
|
||||||
|
|
||||||
for (i = 1; i < sector->numlights; i++)
|
for (i = 1; i < sector->numlights; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -3945,7 +3952,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||||
{
|
{
|
||||||
if (!lightset)
|
if (!lightset)
|
||||||
lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel;
|
lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel;
|
||||||
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||||
colormap = *list[i-1].extra_colormap;
|
colormap = *list[i-1].extra_colormap;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -3963,8 +3970,14 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
||||||
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
|
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
|
||||||
{
|
{
|
||||||
if (!lightset)
|
if (!lightset)
|
||||||
|
{
|
||||||
lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel;
|
lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel;
|
||||||
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
|
||||||
|
if (R_ThingIsSemiBright(spr->mobj))
|
||||||
|
lightlevel = 128 + (lightlevel>>1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||||
colormap = *list[i].extra_colormap;
|
colormap = *list[i].extra_colormap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4279,18 +4292,11 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||||
// colormap test
|
// colormap test
|
||||||
{
|
{
|
||||||
sector_t *sector = spr->mobj->subsector->sector;
|
sector_t *sector = spr->mobj->subsector->sector;
|
||||||
UINT8 lightlevel = 0;
|
INT32 lightlevel = 0;
|
||||||
boolean lightset = true;
|
boolean lightset = HWR_OverrideObjectLightLevel(spr->mobj, &lightlevel);
|
||||||
extracolormap_t *colormap = NULL;
|
extracolormap_t *colormap = NULL;
|
||||||
|
|
||||||
if (R_ThingIsFullBright(spr->mobj))
|
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||||
lightlevel = 255;
|
|
||||||
else if (R_ThingIsFullDark(spr->mobj))
|
|
||||||
lightlevel = 0;
|
|
||||||
else
|
|
||||||
lightset = false;
|
|
||||||
|
|
||||||
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
|
||||||
colormap = sector->extra_colormap;
|
colormap = sector->extra_colormap;
|
||||||
|
|
||||||
if (splat && sector->numlights)
|
if (splat && sector->numlights)
|
||||||
|
|
@ -4300,7 +4306,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||||
if (!lightset)
|
if (!lightset)
|
||||||
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
|
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
|
||||||
|
|
||||||
if (*sector->lightlist[light].extra_colormap && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
if (!R_ThingIsFullBright(spr->mobj) && *sector->lightlist[light].extra_colormap && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||||
colormap = *sector->lightlist[light].extra_colormap;
|
colormap = *sector->lightlist[light].extra_colormap;
|
||||||
}
|
}
|
||||||
else if (!lightset)
|
else if (!lightset)
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ void HWR_MakeScreenFinalTexture(void);
|
||||||
void HWR_DrawScreenFinalTexture(int width, int height);
|
void HWR_DrawScreenFinalTexture(int width, int height);
|
||||||
|
|
||||||
// This stuff is put here so models can use them
|
// This stuff is put here so models can use them
|
||||||
|
boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel);
|
||||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
|
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
|
||||||
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
|
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1324,7 +1324,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
if (spr->mobj->subsector)
|
if (spr->mobj->subsector)
|
||||||
{
|
{
|
||||||
sector_t *sector = spr->mobj->subsector->sector;
|
sector_t *sector = spr->mobj->subsector->sector;
|
||||||
UINT8 lightlevel = 255;
|
INT32 lightlevel = 255;
|
||||||
|
boolean lightset = HWR_OverrideObjectLightLevel(spr->mobj, &lightlevel);
|
||||||
extracolormap_t *colormap = NULL;
|
extracolormap_t *colormap = NULL;
|
||||||
|
|
||||||
if (sector->numlights)
|
if (sector->numlights)
|
||||||
|
|
@ -1333,22 +1334,22 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
||||||
|
|
||||||
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
|
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
|
||||||
|
|
||||||
if (!R_ThingIsFullBright(spr->mobj))
|
if (!lightset)
|
||||||
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
|
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
|
||||||
|
|
||||||
if (*sector->lightlist[light].extra_colormap)
|
if (!R_ThingIsFullBright(spr->mobj) && *sector->lightlist[light].extra_colormap)
|
||||||
colormap = *sector->lightlist[light].extra_colormap;
|
colormap = *sector->lightlist[light].extra_colormap;
|
||||||
}
|
}
|
||||||
else
|
else if (!lightset)
|
||||||
{
|
{
|
||||||
if (!R_ThingIsFullBright(spr->mobj))
|
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
|
||||||
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
|
|
||||||
|
|
||||||
if (sector->extra_colormap)
|
if (sector->extra_colormap)
|
||||||
colormap = sector->extra_colormap;
|
colormap = sector->extra_colormap;
|
||||||
}
|
}
|
||||||
|
|
||||||
//lightlevel = 128 + (lightlevel>>1);
|
if (R_ThingIsSemiBright(spr->mobj))
|
||||||
|
lightlevel = 128 + (lightlevel>>1);
|
||||||
|
|
||||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9295,7 +9295,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
4, // mass
|
4, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPHEIGHT|MF_NOHITLAGFORME, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -9322,7 +9322,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
4, // mass
|
4, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION, // flags
|
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION|MF_NOHITLAGFORME, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -9349,7 +9349,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
4, // mass
|
4, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING, // flags
|
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING|MF_NOHITLAGFORME, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ boolean K_OrbinautJawzCollide(mobj_t *t1, mobj_t *t2)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Player Damage
|
// Player Damage
|
||||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT);
|
P_DamageMobj(t2, t1, t1->target, 1, DMG_WIPEOUT|DMG_WOMBO);
|
||||||
K_KartBouncing(t2, t1);
|
K_KartBouncing(t2, t1);
|
||||||
S_StartSound(t2, sfx_s3k7b);
|
S_StartSound(t2, sfx_s3k7b);
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +143,7 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
|
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL|DMG_WOMBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
damageitem = true;
|
damageitem = true;
|
||||||
|
|
@ -492,12 +492,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
if (t1Condition == true && t2Condition == false)
|
if (t1Condition == true && t2Condition == false)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE);
|
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE|DMG_WOMBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (t1Condition == false && t2Condition == true)
|
else if (t1Condition == false && t2Condition == true)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE);
|
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE|DMG_WOMBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -507,12 +507,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
if (t1Condition == true && t2Condition == false)
|
if (t1Condition == true && t2Condition == false)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE);
|
P_DamageMobj(t2, t1, t1, 1, DMG_TUMBLE|DMG_WOMBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (t1Condition == false && t2Condition == true)
|
else if (t1Condition == false && t2Condition == true)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE);
|
P_DamageMobj(t1, t2, t2, 1, DMG_TUMBLE|DMG_WOMBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -522,12 +522,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
if (t1Condition == true && t2Condition == false)
|
if (t1Condition == true && t2Condition == false)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT);
|
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_WOMBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (t1Condition == false && t2Condition == true)
|
else if (t1Condition == false && t2Condition == true)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT);
|
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_WOMBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -540,12 +540,12 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
||||||
|
|
||||||
if (t1Condition == true && t2Condition == false)
|
if (t1Condition == true && t2Condition == false)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_STEAL);
|
P_DamageMobj(t2, t1, t1, 1, DMG_WIPEOUT|DMG_STEAL|DMG_WOMBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (t1Condition == false && t2Condition == true)
|
else if (t1Condition == false && t2Condition == true)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_STEAL);
|
P_DamageMobj(t1, t2, t2, 1, DMG_WIPEOUT|DMG_STEAL|DMG_WOMBO);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -558,7 +558,7 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
if (t2->player->rings <= 0)
|
if (t2->player->rings <= 0)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t2, t1, t1, 1, DMG_STING);
|
P_DamageMobj(t2, t1, t1, 1, DMG_STING|DMG_WOMBO);
|
||||||
stungT2 = true;
|
stungT2 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -569,7 +569,7 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
||||||
{
|
{
|
||||||
if (t1->player->rings <= 0)
|
if (t1->player->rings <= 0)
|
||||||
{
|
{
|
||||||
P_DamageMobj(t1, t2, t2, 1, DMG_STING);
|
P_DamageMobj(t1, t2, t2, 1, DMG_STING|DMG_WOMBO);
|
||||||
stungT1 = true;
|
stungT1 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
294
src/k_director.c
Normal file
294
src/k_director.c
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
// SONIC ROBO BLAST 2 KART
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file k_director.c
|
||||||
|
/// \brief SRB2kart automatic spectator camera.
|
||||||
|
|
||||||
|
#include "k_kart.h"
|
||||||
|
#include "k_respawn.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "g_game.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "k_director.h"
|
||||||
|
#include "d_netcmd.h"
|
||||||
|
#include "p_local.h"
|
||||||
|
|
||||||
|
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
|
||||||
|
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
|
||||||
|
#define TRANSFERTIME TICRATE // how long to delay reaction shots?
|
||||||
|
#define BREAKAWAYDIST 4000 // how *far* until players considered far apart?
|
||||||
|
#define WALKBACKDIST 600 // how close should a trailing player be before we switch?
|
||||||
|
#define PINCHDIST 30000 // how close should the leader be to be considered "end of race"?
|
||||||
|
|
||||||
|
struct directorinfo directorinfo;
|
||||||
|
|
||||||
|
void K_InitDirector(void)
|
||||||
|
{
|
||||||
|
INT32 playernum;
|
||||||
|
|
||||||
|
directorinfo.cooldown = SWITCHTIME;
|
||||||
|
directorinfo.freeze = 0;
|
||||||
|
directorinfo.attacker = 0;
|
||||||
|
directorinfo.maxdist = 0;
|
||||||
|
|
||||||
|
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
|
||||||
|
{
|
||||||
|
directorinfo.sortedplayers[playernum] = -1;
|
||||||
|
directorinfo.gap[playernum] = INT32_MAX;
|
||||||
|
directorinfo.boredom[playernum] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static fixed_t K_GetFinishGap(INT32 leader, INT32 follower)
|
||||||
|
{
|
||||||
|
fixed_t dista = players[follower].distancetofinish;
|
||||||
|
fixed_t distb = players[leader].distancetofinish;
|
||||||
|
|
||||||
|
if (players[follower].position < players[leader].position)
|
||||||
|
{
|
||||||
|
return distb - dista;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return dista - distb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_UpdateDirectorPositions(void)
|
||||||
|
{
|
||||||
|
INT32 playernum;
|
||||||
|
INT32 position;
|
||||||
|
player_t* target;
|
||||||
|
|
||||||
|
memset(directorinfo.sortedplayers, -1, sizeof(directorinfo.sortedplayers));
|
||||||
|
|
||||||
|
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
|
||||||
|
{
|
||||||
|
target = &players[playernum];
|
||||||
|
|
||||||
|
if (playeringame[playernum] && !target->spectator && target->position > 0)
|
||||||
|
{
|
||||||
|
directorinfo.sortedplayers[target->position - 1] = playernum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (position = 0; position < MAXPLAYERS - 1; position++)
|
||||||
|
{
|
||||||
|
directorinfo.gap[position] = INT32_MAX;
|
||||||
|
|
||||||
|
if (directorinfo.sortedplayers[position] == -1 || directorinfo.sortedplayers[position + 1] == -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
directorinfo.gap[position] = P_ScaleFromMap(K_GetFinishGap(directorinfo.sortedplayers[position], directorinfo.sortedplayers[position + 1]), FRACUNIT);
|
||||||
|
|
||||||
|
if (directorinfo.gap[position] >= BREAKAWAYDIST)
|
||||||
|
{
|
||||||
|
directorinfo.boredom[position] = min(BOREDOMTIME * 2, directorinfo.boredom[position] + 1);
|
||||||
|
}
|
||||||
|
else if (directorinfo.boredom[position] > 0)
|
||||||
|
{
|
||||||
|
directorinfo.boredom[position]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
directorinfo.maxdist = P_ScaleFromMap(players[directorinfo.sortedplayers[0]].distancetofinish, FRACUNIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean K_CanSwitchDirector(void)
|
||||||
|
{
|
||||||
|
INT32 *displayplayerp = &displayplayers[0];
|
||||||
|
|
||||||
|
if (players[*displayplayerp].trickpanel > 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (directorinfo.cooldown > 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_DirectorSwitch(INT32 player, boolean force)
|
||||||
|
{
|
||||||
|
if (P_IsDisplayPlayer(&players[player]))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (players[player].exiting)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!force && !K_CanSwitchDirector())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_ResetView(1, player, true);
|
||||||
|
directorinfo.cooldown = SWITCHTIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void K_DirectorForceSwitch(INT32 player, INT32 time)
|
||||||
|
{
|
||||||
|
if (players[player].exiting)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
directorinfo.attacker = player;
|
||||||
|
directorinfo.freeze = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||||
|
{
|
||||||
|
if (!P_IsDisplayPlayer(player))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inflictor && inflictor->player)
|
||||||
|
{
|
||||||
|
K_DirectorForceSwitch(inflictor->player - players, TRANSFERTIME);
|
||||||
|
}
|
||||||
|
else if (source && source->player)
|
||||||
|
{
|
||||||
|
K_DirectorForceSwitch(source->player - players, TRANSFERTIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_DrawDirectorDebugger(void)
|
||||||
|
{
|
||||||
|
INT32 position;
|
||||||
|
INT32 leader;
|
||||||
|
INT32 follower;
|
||||||
|
INT32 ytxt;
|
||||||
|
|
||||||
|
if (!cv_kartdebugdirector.value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
V_DrawThinString(10, 0, V_70TRANS, va("PLACE"));
|
||||||
|
V_DrawThinString(40, 0, V_70TRANS, va("CONF?"));
|
||||||
|
V_DrawThinString(80, 0, V_70TRANS, va("GAP"));
|
||||||
|
V_DrawThinString(120, 0, V_70TRANS, va("BORED"));
|
||||||
|
V_DrawThinString(150, 0, V_70TRANS, va("COOLDOWN: %d", directorinfo.cooldown));
|
||||||
|
V_DrawThinString(230, 0, V_70TRANS, va("MAXDIST: %d", directorinfo.maxdist));
|
||||||
|
|
||||||
|
for (position = 0; position < MAXPLAYERS - 1; position++)
|
||||||
|
{
|
||||||
|
ytxt = 10 * (position + 1);
|
||||||
|
leader = directorinfo.sortedplayers[position];
|
||||||
|
follower = directorinfo.sortedplayers[position + 1];
|
||||||
|
|
||||||
|
if (leader == -1 || follower == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
V_DrawThinString(10, ytxt, V_70TRANS, va("%d", position));
|
||||||
|
V_DrawThinString(20, ytxt, V_70TRANS, va("%d", position + 1));
|
||||||
|
|
||||||
|
if (players[leader].positiondelay)
|
||||||
|
{
|
||||||
|
V_DrawThinString(40, ytxt, V_70TRANS, va("NG"));
|
||||||
|
}
|
||||||
|
|
||||||
|
V_DrawThinString(80, ytxt, V_70TRANS, va("%d", directorinfo.gap[position]));
|
||||||
|
|
||||||
|
if (directorinfo.boredom[position] >= BOREDOMTIME)
|
||||||
|
{
|
||||||
|
V_DrawThinString(120, ytxt, V_70TRANS, va("BORED"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
V_DrawThinString(120, ytxt, V_70TRANS, va("%d", directorinfo.boredom[position]));
|
||||||
|
}
|
||||||
|
|
||||||
|
V_DrawThinString(150, ytxt, V_70TRANS, va("%s", player_names[leader]));
|
||||||
|
V_DrawThinString(230, ytxt, V_70TRANS, va("%s", player_names[follower]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_UpdateDirector(void)
|
||||||
|
{
|
||||||
|
INT32 *displayplayerp = &displayplayers[0];
|
||||||
|
INT32 targetposition;
|
||||||
|
|
||||||
|
if (!cv_director.value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
K_UpdateDirectorPositions();
|
||||||
|
|
||||||
|
if (directorinfo.cooldown > 0) {
|
||||||
|
directorinfo.cooldown--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle pending forced switches
|
||||||
|
if (directorinfo.freeze > 0)
|
||||||
|
{
|
||||||
|
if (!(--directorinfo.freeze))
|
||||||
|
K_DirectorSwitch(directorinfo.attacker, true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// aaight, time to walk through the standings to find the first interesting pair
|
||||||
|
// NB: targetposition/sortedplayers is 0-indexed, aiming at the "back half" of a given pair by default.
|
||||||
|
// we adjust for this when comparing to player->position or when looking at the leading player, Don't Freak Out
|
||||||
|
for (targetposition = 1; targetposition < MAXPLAYERS; targetposition++)
|
||||||
|
{
|
||||||
|
INT32 target;
|
||||||
|
|
||||||
|
// you are out of players, try again
|
||||||
|
if (directorinfo.sortedplayers[targetposition] == -1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pair too far apart? try the next one
|
||||||
|
if (directorinfo.boredom[targetposition - 1] >= BOREDOMTIME)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pair finished? try the next one
|
||||||
|
if (players[directorinfo.sortedplayers[targetposition]].exiting)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't risk switching away from forward pairs at race end, might miss something!
|
||||||
|
if (directorinfo.maxdist > PINCHDIST)
|
||||||
|
{
|
||||||
|
// if the "next" player is close enough, they should be able to see everyone fine!
|
||||||
|
// walk back through the standings to find a vantage that gets everyone in frame.
|
||||||
|
// (also creates a pretty cool effect w/ overtakes at speed)
|
||||||
|
while (targetposition < MAXPLAYERS && directorinfo.gap[targetposition] < WALKBACKDIST)
|
||||||
|
{
|
||||||
|
targetposition++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target = directorinfo.sortedplayers[targetposition];
|
||||||
|
|
||||||
|
// if we're certain the back half of the pair is actually in this position, try to switch
|
||||||
|
if (*displayplayerp != target && !players[target].positiondelay)
|
||||||
|
{
|
||||||
|
K_DirectorSwitch(target, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// even if we're not certain, if we're certain we're watching the WRONG player, try to switch
|
||||||
|
if (players[*displayplayerp].position != targetposition+1 && !players[target].positiondelay)
|
||||||
|
{
|
||||||
|
K_DirectorSwitch(target, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/k_director.h
Normal file
21
src/k_director.h
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
// SONIC ROBO BLAST 2 KART
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file k_director.h
|
||||||
|
/// \brief SRB2kart automatic spectator camera.
|
||||||
|
|
||||||
|
extern struct directorinfo
|
||||||
|
{
|
||||||
|
tic_t cooldown; // how long has it been since we last switched?
|
||||||
|
tic_t freeze; // when nonzero, fixed switch pending, freeze logic!
|
||||||
|
INT32 attacker; // who to switch to when freeze delay elapses
|
||||||
|
INT32 maxdist; // how far is the closest player from finishing?
|
||||||
|
|
||||||
|
INT32 sortedplayers[MAXPLAYERS]; // position-1 goes in, player index comes out.
|
||||||
|
INT32 gap[MAXPLAYERS]; // gap between a given position and their closest pursuer
|
||||||
|
INT32 boredom[MAXPLAYERS]; // how long has a given position had no credible attackers?
|
||||||
|
} directorinfo;
|
||||||
|
|
||||||
|
void K_InitDirector(void);
|
||||||
|
void K_UpdateDirector(void);
|
||||||
|
void K_DrawDirectorDebugger(void);
|
||||||
|
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_color.h"
|
#include "k_color.h"
|
||||||
|
#include "k_director.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
|
|
@ -4504,6 +4505,7 @@ void K_drawKartHUD(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
K_DrawWaypointDebugger();
|
K_DrawWaypointDebugger();
|
||||||
|
K_DrawDirectorDebugger();
|
||||||
|
|
||||||
if (gametype == GT_BATTLE)
|
if (gametype == GT_BATTLE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
275
src/k_kart.c
275
src/k_kart.c
|
|
@ -34,6 +34,7 @@
|
||||||
#include "k_bot.h"
|
#include "k_bot.h"
|
||||||
#include "k_hud.h"
|
#include "k_hud.h"
|
||||||
#include "k_terrain.h"
|
#include "k_terrain.h"
|
||||||
|
#include "k_director.h"
|
||||||
|
|
||||||
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
|
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
|
||||||
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
|
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
|
||||||
|
|
@ -250,7 +251,6 @@ void K_RegisterKartStuff(void)
|
||||||
|
|
||||||
CV_RegisterVar(&cv_kartdebugitem);
|
CV_RegisterVar(&cv_kartdebugitem);
|
||||||
CV_RegisterVar(&cv_kartdebugamount);
|
CV_RegisterVar(&cv_kartdebugamount);
|
||||||
CV_RegisterVar(&cv_kartdebugshrink);
|
|
||||||
CV_RegisterVar(&cv_kartallowgiveitem);
|
CV_RegisterVar(&cv_kartallowgiveitem);
|
||||||
CV_RegisterVar(&cv_kartdebugdistribution);
|
CV_RegisterVar(&cv_kartdebugdistribution);
|
||||||
CV_RegisterVar(&cv_kartdebughuddrop);
|
CV_RegisterVar(&cv_kartdebughuddrop);
|
||||||
|
|
@ -260,6 +260,7 @@ void K_RegisterKartStuff(void)
|
||||||
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
||||||
CV_RegisterVar(&cv_kartdebugnodes);
|
CV_RegisterVar(&cv_kartdebugnodes);
|
||||||
CV_RegisterVar(&cv_kartdebugcolorize);
|
CV_RegisterVar(&cv_kartdebugcolorize);
|
||||||
|
CV_RegisterVar(&cv_kartdebugdirector);
|
||||||
}
|
}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
@ -2903,6 +2904,28 @@ static void K_GetKartBoostPower(player_t *player)
|
||||||
player->numboosts = numboosts;
|
player->numboosts = numboosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fixed_t K_GrowShrinkSpeedMul(player_t *player)
|
||||||
|
{
|
||||||
|
fixed_t scaleDiff = player->mo->scale - mapobjectscale;
|
||||||
|
fixed_t playerScale = FixedDiv(player->mo->scale, mapobjectscale);
|
||||||
|
fixed_t speedMul = FRACUNIT;
|
||||||
|
|
||||||
|
if (scaleDiff > 0)
|
||||||
|
{
|
||||||
|
// Grown
|
||||||
|
// Change x2 speed into x1.5
|
||||||
|
speedMul = FixedDiv(FixedMul(playerScale, GROW_PHYSICS_SCALE), GROW_SCALE);
|
||||||
|
}
|
||||||
|
else if (scaleDiff < 0)
|
||||||
|
{
|
||||||
|
// Shrunk
|
||||||
|
// Change x0.5 speed into x0.75
|
||||||
|
speedMul = FixedDiv(FixedMul(playerScale, SHRINK_PHYSICS_SCALE), SHRINK_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return speedMul;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns kart speed from a stat. Boost power and scale are NOT taken into account, no player or object is necessary.
|
// Returns kart speed from a stat. Boost power and scale are NOT taken into account, no player or object is necessary.
|
||||||
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed)
|
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed)
|
||||||
{
|
{
|
||||||
|
|
@ -2919,9 +2942,8 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed)
|
||||||
|
|
||||||
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
|
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
|
||||||
{
|
{
|
||||||
fixed_t finalspeed;
|
const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
|
||||||
|
fixed_t finalspeed = K_GetKartSpeedFromStat(player->kartspeed);
|
||||||
finalspeed = K_GetKartSpeedFromStat(player->kartspeed);
|
|
||||||
|
|
||||||
if (player->spheres > 0)
|
if (player->spheres > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -2942,17 +2964,22 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->mo && !P_MobjWasRemoved(player->mo))
|
finalspeed = FixedMul(finalspeed, mapobjectscale);
|
||||||
finalspeed = FixedMul(finalspeed, player->mo->scale);
|
|
||||||
|
|
||||||
if (doboostpower)
|
if (doboostpower == true)
|
||||||
{
|
{
|
||||||
|
if (mobjValid == true)
|
||||||
|
{
|
||||||
|
// Scale with the player.
|
||||||
|
finalspeed = FixedMul(finalspeed, K_GrowShrinkSpeedMul(player));
|
||||||
|
}
|
||||||
|
|
||||||
if (K_PlayerUsesBotMovement(player))
|
if (K_PlayerUsesBotMovement(player))
|
||||||
{
|
{
|
||||||
finalspeed = FixedMul(finalspeed, K_BotTopSpeedRubberband(player));
|
finalspeed = FixedMul(finalspeed, K_BotTopSpeedRubberband(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
return FixedMul(finalspeed, player->boostpower+player->speedboost);
|
finalspeed = FixedMul(finalspeed, player->boostpower + player->speedboost);
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalspeed;
|
return finalspeed;
|
||||||
|
|
@ -2992,6 +3019,34 @@ UINT16 K_GetKartFlashing(player_t *player)
|
||||||
return tics;
|
return tics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean K_PlayerShrinkCheat(player_t *player)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(player->pflags & PF_SHRINKACTIVE)
|
||||||
|
&& (player->bot == false)
|
||||||
|
&& (modeattacking == false) // Anyone want to make another record attack category?
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_UpdateShrinkCheat(player_t *player)
|
||||||
|
{
|
||||||
|
const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
|
||||||
|
|
||||||
|
if (player->pflags & PF_SHRINKME)
|
||||||
|
{
|
||||||
|
player->pflags |= PF_SHRINKACTIVE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->pflags &= ~PF_SHRINKACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mobjValid == true && K_PlayerShrinkCheat(player) == true)
|
||||||
|
{
|
||||||
|
player->mo->destscale = FixedMul(mapobjectscale, SHRINK_SCALE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean K_KartKickstart(player_t *player)
|
boolean K_KartKickstart(player_t *player)
|
||||||
{
|
{
|
||||||
return ((player->pflags & PF_KICKSTARTACCEL)
|
return ((player->pflags & PF_KICKSTARTACCEL)
|
||||||
|
|
@ -3098,7 +3153,7 @@ angle_t K_MomentumAngle(mobj_t *mo)
|
||||||
|
|
||||||
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage)
|
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage)
|
||||||
{
|
{
|
||||||
if (mo == NULL || P_MobjWasRemoved(mo))
|
if (mo == NULL || P_MobjWasRemoved(mo) || (mo->flags & MF_NOHITLAGFORME && mo->type != MT_PLAYER))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3234,6 +3289,8 @@ void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 typ
|
||||||
(void)inflictor;
|
(void)inflictor;
|
||||||
(void)source;
|
(void)source;
|
||||||
|
|
||||||
|
K_DirectorFollowAttack(player, inflictor, source);
|
||||||
|
|
||||||
player->spinouttype = type;
|
player->spinouttype = type;
|
||||||
|
|
||||||
if (( player->spinouttype & KSPIN_THRUST ))
|
if (( player->spinouttype & KSPIN_THRUST ))
|
||||||
|
|
@ -3262,8 +3319,11 @@ static void K_RemoveGrowShrink(player_t *player)
|
||||||
|
|
||||||
player->mo->scalespeed = mapobjectscale/TICRATE;
|
player->mo->scalespeed = mapobjectscale/TICRATE;
|
||||||
player->mo->destscale = mapobjectscale;
|
player->mo->destscale = mapobjectscale;
|
||||||
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
|
|
||||||
player->mo->destscale = (6*player->mo->destscale)/8;
|
if (K_PlayerShrinkCheat(player) == true)
|
||||||
|
{
|
||||||
|
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
player->growshrinktimer = 0;
|
player->growshrinktimer = 0;
|
||||||
|
|
@ -3276,6 +3336,8 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||||
fixed_t gravityadjust;
|
fixed_t gravityadjust;
|
||||||
(void)source;
|
(void)source;
|
||||||
|
|
||||||
|
K_DirectorFollowAttack(player, inflictor, source);
|
||||||
|
|
||||||
player->tumbleBounces = 1;
|
player->tumbleBounces = 1;
|
||||||
|
|
||||||
if (player->tripWireState == TRIP_PASSED)
|
if (player->tripWireState == TRIP_PASSED)
|
||||||
|
|
@ -3412,6 +3474,8 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A
|
||||||
|
|
||||||
(void)source;
|
(void)source;
|
||||||
|
|
||||||
|
K_DirectorFollowAttack(player, inflictor, source);
|
||||||
|
|
||||||
player->mo->momz = 18*mapobjectscale*P_MobjFlip(player->mo); // please stop forgetting mobjflip checks!!!!
|
player->mo->momz = 18*mapobjectscale*P_MobjFlip(player->mo); // please stop forgetting mobjflip checks!!!!
|
||||||
player->mo->momx = player->mo->momy = 0;
|
player->mo->momx = player->mo->momy = 0;
|
||||||
|
|
||||||
|
|
@ -3787,24 +3851,56 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color)
|
||||||
|
|
||||||
#undef MINEQUAKEDIST
|
#undef MINEQUAKEDIST
|
||||||
|
|
||||||
|
fixed_t K_ItemScaleForPlayer(player_t *player)
|
||||||
|
{
|
||||||
|
switch (player->itemscale)
|
||||||
|
{
|
||||||
|
case ITEMSCALE_GROW:
|
||||||
|
return FixedMul(GROW_SCALE, mapobjectscale);
|
||||||
|
|
||||||
|
case ITEMSCALE_SHRINK:
|
||||||
|
return FixedMul(SHRINK_SCALE, mapobjectscale);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return mapobjectscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, INT32 flags2, fixed_t speed)
|
static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, INT32 flags2, fixed_t speed)
|
||||||
{
|
{
|
||||||
mobj_t *th;
|
mobj_t *th;
|
||||||
fixed_t x, y, z;
|
fixed_t x, y, z;
|
||||||
fixed_t finalspeed = speed;
|
fixed_t finalspeed = speed;
|
||||||
|
fixed_t finalscale = mapobjectscale;
|
||||||
mobj_t *throwmo;
|
mobj_t *throwmo;
|
||||||
|
|
||||||
if (source->player && source->player->speed > K_GetKartSpeed(source->player, false))
|
if (source->player != NULL)
|
||||||
{
|
{
|
||||||
angle_t input = source->angle - an;
|
if (source->player->itemscale == ITEMSCALE_SHRINK)
|
||||||
boolean invert = (input > ANGLE_180);
|
{
|
||||||
if (invert)
|
// Nerf the base item speed a bit.
|
||||||
input = InvAngle(input);
|
finalspeed = FixedMul(finalspeed, SHRINK_PHYSICS_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
finalspeed = max(speed, FixedMul(speed, FixedMul(
|
if (source->player->speed > K_GetKartSpeed(source->player, false))
|
||||||
FixedDiv(source->player->speed, K_GetKartSpeed(source->player, false)), // Multiply speed to be proportional to your own, boosted maxspeed.
|
{
|
||||||
(((180<<FRACBITS) - AngleFixed(input)) / 180) // multiply speed based on angle diff... i.e: don't do this for firing backward :V
|
angle_t input = source->angle - an;
|
||||||
)));
|
boolean invert = (input > ANGLE_180);
|
||||||
|
if (invert)
|
||||||
|
input = InvAngle(input);
|
||||||
|
|
||||||
|
finalspeed = max(speed, FixedMul(speed, FixedMul(
|
||||||
|
FixedDiv(source->player->speed, K_GetKartSpeed(source->player, false)), // Multiply speed to be proportional to your own, boosted maxspeed.
|
||||||
|
(((180<<FRACBITS) - AngleFixed(input)) / 180) // multiply speed based on angle diff... i.e: don't do this for firing backward :V
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
finalscale = K_ItemScaleForPlayer(source->player);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == MT_BUBBLESHIELDTRAP)
|
||||||
|
{
|
||||||
|
finalscale = source->scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = source->x + source->momx + FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT));
|
x = source->x + source->momx + FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT));
|
||||||
|
|
@ -3823,8 +3919,8 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
|
||||||
|
|
||||||
P_SetTarget(&th->target, source);
|
P_SetTarget(&th->target, source);
|
||||||
|
|
||||||
P_SetScale(th, source->scale);
|
P_SetScale(th, finalscale);
|
||||||
th->destscale = source->destscale;
|
th->destscale = finalscale;
|
||||||
|
|
||||||
if (P_IsObjectOnGround(source))
|
if (P_IsObjectOnGround(source))
|
||||||
{
|
{
|
||||||
|
|
@ -3850,6 +3946,11 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I
|
||||||
th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT));
|
th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT));
|
||||||
th->momz = source->momz;
|
th->momz = source->momz;
|
||||||
|
|
||||||
|
if (source->player != NULL)
|
||||||
|
{
|
||||||
|
th->cusval = source->player->itemscale;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case MT_ORBINAUT:
|
case MT_ORBINAUT:
|
||||||
|
|
@ -4744,13 +4845,15 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
fixed_t finalscale = K_ItemScaleForPlayer(player);
|
||||||
|
|
||||||
player->bananadrag = 0; // RESET timer, for multiple bananas
|
player->bananadrag = 0; // RESET timer, for multiple bananas
|
||||||
|
|
||||||
if (dir > 0)
|
if (dir > 0)
|
||||||
{
|
{
|
||||||
// Shoot forward
|
// Shoot forward
|
||||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, mapthing);
|
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height/2, mapthing);
|
||||||
//K_FlipFromObject(mo, player->mo);
|
|
||||||
// These are really weird so let's make it a very specific case to make SURE it works...
|
// These are really weird so let's make it a very specific case to make SURE it works...
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
{
|
{
|
||||||
|
|
@ -4777,6 +4880,9 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
|
||||||
|
|
||||||
if (mo->eflags & MFE_UNDERWATER)
|
if (mo->eflags & MFE_UNDERWATER)
|
||||||
mo->momz = (117 * mo->momz) / 200;
|
mo->momz = (117 * mo->momz) / 200;
|
||||||
|
|
||||||
|
P_SetScale(mo, finalscale);
|
||||||
|
mo->destscale = finalscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is the small graphic effect that plops in you when you throw an item:
|
// this is the small graphic effect that plops in you when you throw an item:
|
||||||
|
|
@ -4791,6 +4897,9 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
|
||||||
}
|
}
|
||||||
|
|
||||||
throwmo->movecount = 0; // above player
|
throwmo->movecount = 0; // above player
|
||||||
|
|
||||||
|
P_SetScale(throwmo, finalscale);
|
||||||
|
throwmo->destscale = finalscale;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -4828,8 +4937,8 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing,
|
||||||
mo->threshold = 10;
|
mo->threshold = 10;
|
||||||
P_SetTarget(&mo->target, player->mo);
|
P_SetTarget(&mo->target, player->mo);
|
||||||
|
|
||||||
P_SetScale(mo, player->mo->scale);
|
P_SetScale(mo, finalscale);
|
||||||
mo->destscale = player->mo->destscale;
|
mo->destscale = finalscale;
|
||||||
|
|
||||||
if (P_IsObjectOnGround(player->mo))
|
if (P_IsObjectOnGround(player->mo))
|
||||||
{
|
{
|
||||||
|
|
@ -4899,6 +5008,10 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter)
|
||||||
mine->floorz = origMine->floorz;
|
mine->floorz = origMine->floorz;
|
||||||
mine->ceilingz = origMine->ceilingz;
|
mine->ceilingz = origMine->ceilingz;
|
||||||
|
|
||||||
|
P_SetScale(mine, origMine->scale);
|
||||||
|
mine->destscale = origMine->destscale;
|
||||||
|
mine->scalespeed = origMine->scalespeed;
|
||||||
|
|
||||||
// Copy interp data
|
// Copy interp data
|
||||||
mine->old_angle = origMine->old_angle;
|
mine->old_angle = origMine->old_angle;
|
||||||
mine->old_x = origMine->old_x;
|
mine->old_x = origMine->old_x;
|
||||||
|
|
@ -4907,8 +5020,7 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter)
|
||||||
|
|
||||||
// Since we aren't using P_KillMobj, we need to clean up the hnext reference
|
// Since we aren't using P_KillMobj, we need to clean up the hnext reference
|
||||||
P_SetTarget(&mineOwner->hnext, NULL);
|
P_SetTarget(&mineOwner->hnext, NULL);
|
||||||
mineOwner->player->bananadrag = 0;
|
K_UnsetItemOut(mineOwner->player);
|
||||||
mineOwner->player->pflags &= ~PF_ITEMOUT;
|
|
||||||
|
|
||||||
if (mineOwner->player->itemamount)
|
if (mineOwner->player->itemamount)
|
||||||
{
|
{
|
||||||
|
|
@ -5065,7 +5177,7 @@ static void K_DoHyudoroSteal(player_t *player)
|
||||||
|
|
||||||
player->itemtype = KITEM_KITCHENSINK;
|
player->itemtype = KITEM_KITCHENSINK;
|
||||||
player->itemamount = 1;
|
player->itemamount = 1;
|
||||||
player->pflags &= ~PF_ITEMOUT;
|
K_UnsetItemOut(player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((gametype == GT_RACE && player->position == 1) || numplayers == 0) // No-one can be stolen from? Oh well...
|
else if ((gametype == GT_RACE && player->position == 1) || numplayers == 0) // No-one can be stolen from? Oh well...
|
||||||
|
|
@ -5091,11 +5203,11 @@ static void K_DoHyudoroSteal(player_t *player)
|
||||||
|
|
||||||
player->itemtype = players[stealplayer].itemtype;
|
player->itemtype = players[stealplayer].itemtype;
|
||||||
player->itemamount = players[stealplayer].itemamount;
|
player->itemamount = players[stealplayer].itemamount;
|
||||||
player->pflags &= ~PF_ITEMOUT;
|
K_UnsetItemOut(player);
|
||||||
|
|
||||||
players[stealplayer].itemtype = KITEM_NONE;
|
players[stealplayer].itemtype = KITEM_NONE;
|
||||||
players[stealplayer].itemamount = 0;
|
players[stealplayer].itemamount = 0;
|
||||||
players[stealplayer].pflags &= ~PF_ITEMOUT;
|
K_UnsetItemOut(&players[stealplayer]);
|
||||||
|
|
||||||
if (P_IsDisplayPlayer(&players[stealplayer]) && !r_splitscreen)
|
if (P_IsDisplayPlayer(&players[stealplayer]) && !r_splitscreen)
|
||||||
S_StartSound(NULL, sfx_s3k92);
|
S_StartSound(NULL, sfx_s3k92);
|
||||||
|
|
@ -5201,9 +5313,13 @@ static void K_DoShrink(player_t *user)
|
||||||
if (players[i].mo && !P_MobjWasRemoved(players[i].mo))
|
if (players[i].mo && !P_MobjWasRemoved(players[i].mo))
|
||||||
{
|
{
|
||||||
players[i].mo->scalespeed = mapobjectscale/TICRATE;
|
players[i].mo->scalespeed = mapobjectscale/TICRATE;
|
||||||
players[i].mo->destscale = (6*mapobjectscale)/8;
|
players[i].mo->destscale = FixedMul(mapobjectscale, SHRINK_SCALE);
|
||||||
if (cv_kartdebugshrink.value && !modeattacking && !players[i].bot)
|
|
||||||
players[i].mo->destscale = (6*players[i].mo->destscale)/8;
|
if (K_PlayerShrinkCheat(&players[i]) == true)
|
||||||
|
{
|
||||||
|
players[i].mo->destscale = FixedMul(players[i].mo->destscale, SHRINK_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
S_StartSound(players[i].mo, sfx_kc59);
|
S_StartSound(players[i].mo, sfx_kc59);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5414,7 +5530,7 @@ void K_DropHnextList(player_t *player, boolean keepshields)
|
||||||
player->curshield = KSHIELD_NONE;
|
player->curshield = KSHIELD_NONE;
|
||||||
player->itemtype = KITEM_NONE;
|
player->itemtype = KITEM_NONE;
|
||||||
player->itemamount = 0;
|
player->itemamount = 0;
|
||||||
player->pflags &= ~PF_ITEMOUT;
|
K_UnsetItemOut(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextwork = work->hnext;
|
nextwork = work->hnext;
|
||||||
|
|
@ -5463,6 +5579,10 @@ void K_DropHnextList(player_t *player, boolean keepshields)
|
||||||
|
|
||||||
dropwork->angle = work->angle;
|
dropwork->angle = work->angle;
|
||||||
|
|
||||||
|
P_SetScale(dropwork, work->scale);
|
||||||
|
dropwork->destscale = work->destscale;
|
||||||
|
dropwork->scalespeed = work->scalespeed;
|
||||||
|
|
||||||
dropwork->flags |= MF_NOCLIPTHING;
|
dropwork->flags |= MF_NOCLIPTHING;
|
||||||
dropwork->flags2 = work->flags2;
|
dropwork->flags2 = work->flags2;
|
||||||
dropwork->eflags = work->eflags;
|
dropwork->eflags = work->eflags;
|
||||||
|
|
@ -5552,7 +5672,7 @@ void K_DropHnextList(player_t *player, boolean keepshields)
|
||||||
&& (dropall || (--player->itemamount <= 0)))
|
&& (dropall || (--player->itemamount <= 0)))
|
||||||
{
|
{
|
||||||
player->itemamount = 0;
|
player->itemamount = 0;
|
||||||
player->pflags &= ~PF_ITEMOUT;
|
K_UnsetItemOut(player);
|
||||||
player->itemtype = KITEM_NONE;
|
player->itemtype = KITEM_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5927,6 +6047,8 @@ static void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z
|
||||||
// Move the hnext chain!
|
// Move the hnext chain!
|
||||||
static void K_MoveHeldObjects(player_t *player)
|
static void K_MoveHeldObjects(player_t *player)
|
||||||
{
|
{
|
||||||
|
fixed_t finalscale = INT32_MAX;
|
||||||
|
|
||||||
if (!player->mo)
|
if (!player->mo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -5938,7 +6060,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
else if (player->pflags & PF_ITEMOUT)
|
else if (player->pflags & PF_ITEMOUT)
|
||||||
{
|
{
|
||||||
player->itemamount = 0;
|
player->itemamount = 0;
|
||||||
player->pflags &= ~PF_ITEMOUT;
|
K_UnsetItemOut(player);
|
||||||
player->itemtype = KITEM_NONE;
|
player->itemtype = KITEM_NONE;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -5954,12 +6076,14 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
else if (player->pflags & PF_ITEMOUT)
|
else if (player->pflags & PF_ITEMOUT)
|
||||||
{
|
{
|
||||||
player->itemamount = 0;
|
player->itemamount = 0;
|
||||||
player->pflags &= ~PF_ITEMOUT;
|
K_UnsetItemOut(player);
|
||||||
player->itemtype = KITEM_NONE;
|
player->itemtype = KITEM_NONE;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalscale = K_ItemScaleForPlayer(player);
|
||||||
|
|
||||||
switch (player->mo->hnext->type)
|
switch (player->mo->hnext->type)
|
||||||
{
|
{
|
||||||
case MT_ORBINAUT_SHIELD: // Kart orbit items
|
case MT_ORBINAUT_SHIELD: // Kart orbit items
|
||||||
|
|
@ -5998,7 +6122,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
cur->eflags &= ~MFE_VERTICALFLIP;
|
cur->eflags &= ~MFE_VERTICALFLIP;
|
||||||
|
|
||||||
// Shrink your items if the player shrunk too.
|
// Shrink your items if the player shrunk too.
|
||||||
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), player->mo->scale)));
|
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), finalscale)));
|
||||||
|
|
||||||
if (P_MobjFlip(cur) > 0)
|
if (P_MobjFlip(cur) > 0)
|
||||||
z = player->mo->z;
|
z = player->mo->z;
|
||||||
|
|
@ -6029,7 +6153,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center it during the scale up animation
|
// Center it during the scale up animation
|
||||||
z += (FixedMul(mobjinfo[cur->type].height, player->mo->scale - cur->scale)>>1) * P_MobjFlip(cur);
|
z += (FixedMul(mobjinfo[cur->type].height, finalscale - cur->scale)>>1) * P_MobjFlip(cur);
|
||||||
|
|
||||||
cur->z = z;
|
cur->z = z;
|
||||||
cur->momx = cur->momy = 0;
|
cur->momx = cur->momy = 0;
|
||||||
|
|
@ -6091,7 +6215,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Shrink your items if the player shrunk too.
|
// Shrink your items if the player shrunk too.
|
||||||
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), player->mo->scale)));
|
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), finalscale)));
|
||||||
|
|
||||||
ang = targ->angle;
|
ang = targ->angle;
|
||||||
targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, dist);
|
targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, dist);
|
||||||
|
|
@ -8682,6 +8806,31 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz)
|
||||||
#undef RADIUSSCALING
|
#undef RADIUSSCALING
|
||||||
#undef MINRADIUS
|
#undef MINRADIUS
|
||||||
|
|
||||||
|
void K_SetItemOut(player_t *player)
|
||||||
|
{
|
||||||
|
player->pflags |= PF_ITEMOUT;
|
||||||
|
|
||||||
|
if (player->mo->scale >= FixedMul(GROW_PHYSICS_SCALE, mapobjectscale))
|
||||||
|
{
|
||||||
|
player->itemscale = ITEMSCALE_GROW;
|
||||||
|
}
|
||||||
|
else if (player->mo->scale <= FixedMul(SHRINK_PHYSICS_SCALE, mapobjectscale))
|
||||||
|
{
|
||||||
|
player->itemscale = ITEMSCALE_SHRINK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->itemscale = ITEMSCALE_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_UnsetItemOut(player_t *player)
|
||||||
|
{
|
||||||
|
player->pflags &= ~PF_ITEMOUT;
|
||||||
|
player->itemscale = ITEMSCALE_NORMAL;
|
||||||
|
player->bananadrag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// K_MoveKartPlayer
|
// K_MoveKartPlayer
|
||||||
//
|
//
|
||||||
|
|
@ -8782,7 +8931,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
}
|
}
|
||||||
else if (player->itemamount == 0)
|
else if (player->itemamount == 0)
|
||||||
{
|
{
|
||||||
player->pflags &= ~PF_ITEMOUT;
|
K_UnsetItemOut(player);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -8857,7 +9006,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mobj_t *prev = player->mo;
|
mobj_t *prev = player->mo;
|
||||||
|
|
||||||
//K_PlayAttackTaunt(player->mo);
|
//K_PlayAttackTaunt(player->mo);
|
||||||
player->pflags |= PF_ITEMOUT;
|
K_SetItemOut(player);
|
||||||
S_StartSound(player->mo, sfx_s254);
|
S_StartSound(player->mo, sfx_s254);
|
||||||
|
|
||||||
for (moloop = 0; moloop < player->itemamount; moloop++)
|
for (moloop = 0; moloop < player->itemamount; moloop++)
|
||||||
|
|
@ -8872,6 +9021,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mo->threshold = 10;
|
mo->threshold = 10;
|
||||||
mo->movecount = player->itemamount;
|
mo->movecount = player->itemamount;
|
||||||
mo->movedir = moloop+1;
|
mo->movedir = moloop+1;
|
||||||
|
mo->cusval = player->itemscale;
|
||||||
P_SetTarget(&mo->target, player->mo);
|
P_SetTarget(&mo->target, player->mo);
|
||||||
P_SetTarget(&mo->hprev, prev);
|
P_SetTarget(&mo->hprev, prev);
|
||||||
P_SetTarget(&prev->hnext, mo);
|
P_SetTarget(&prev->hnext, mo);
|
||||||
|
|
@ -8901,6 +9051,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mo->threshold = 10;
|
mo->threshold = 10;
|
||||||
mo->movecount = 1;
|
mo->movecount = 1;
|
||||||
mo->movedir = 1;
|
mo->movedir = 1;
|
||||||
|
mo->cusval = player->itemscale;
|
||||||
P_SetTarget(&mo->target, player->mo);
|
P_SetTarget(&mo->target, player->mo);
|
||||||
P_SetTarget(&player->mo->hnext, mo);
|
P_SetTarget(&player->mo->hnext, mo);
|
||||||
}
|
}
|
||||||
|
|
@ -8915,7 +9066,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mobj_t *prev = player->mo;
|
mobj_t *prev = player->mo;
|
||||||
|
|
||||||
//K_PlayAttackTaunt(player->mo);
|
//K_PlayAttackTaunt(player->mo);
|
||||||
player->pflags |= PF_ITEMOUT;
|
K_SetItemOut(player);
|
||||||
S_StartSound(player->mo, sfx_s3k3a);
|
S_StartSound(player->mo, sfx_s3k3a);
|
||||||
|
|
||||||
for (moloop = 0; moloop < player->itemamount; moloop++)
|
for (moloop = 0; moloop < player->itemamount; moloop++)
|
||||||
|
|
@ -8933,6 +9084,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mo->movecount = player->itemamount;
|
mo->movecount = player->itemamount;
|
||||||
mo->movedir = mo->lastlook = moloop+1;
|
mo->movedir = mo->lastlook = moloop+1;
|
||||||
mo->color = player->skincolor;
|
mo->color = player->skincolor;
|
||||||
|
mo->cusval = player->itemscale;
|
||||||
P_SetTarget(&mo->target, player->mo);
|
P_SetTarget(&mo->target, player->mo);
|
||||||
P_SetTarget(&mo->hprev, prev);
|
P_SetTarget(&mo->hprev, prev);
|
||||||
P_SetTarget(&prev->hnext, mo);
|
P_SetTarget(&prev->hnext, mo);
|
||||||
|
|
@ -8956,7 +9108,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mobj_t *prev = player->mo;
|
mobj_t *prev = player->mo;
|
||||||
|
|
||||||
//K_PlayAttackTaunt(player->mo);
|
//K_PlayAttackTaunt(player->mo);
|
||||||
player->pflags |= PF_ITEMOUT;
|
K_SetItemOut(player);
|
||||||
S_StartSound(player->mo, sfx_s3k3a);
|
S_StartSound(player->mo, sfx_s3k3a);
|
||||||
|
|
||||||
for (moloop = 0; moloop < player->itemamount; moloop++)
|
for (moloop = 0; moloop < player->itemamount; moloop++)
|
||||||
|
|
@ -8973,6 +9125,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mo->threshold = 10;
|
mo->threshold = 10;
|
||||||
mo->movecount = player->itemamount;
|
mo->movecount = player->itemamount;
|
||||||
mo->movedir = mo->lastlook = moloop+1;
|
mo->movedir = mo->lastlook = moloop+1;
|
||||||
|
mo->cusval = player->itemscale;
|
||||||
P_SetTarget(&mo->target, player->mo);
|
P_SetTarget(&mo->target, player->mo);
|
||||||
P_SetTarget(&mo->hprev, prev);
|
P_SetTarget(&mo->hprev, prev);
|
||||||
P_SetTarget(&prev->hnext, mo);
|
P_SetTarget(&prev->hnext, mo);
|
||||||
|
|
@ -8994,7 +9147,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
||||||
{
|
{
|
||||||
mobj_t *mo;
|
mobj_t *mo;
|
||||||
player->pflags |= PF_ITEMOUT;
|
K_SetItemOut(player);
|
||||||
S_StartSound(player->mo, sfx_s254);
|
S_StartSound(player->mo, sfx_s254);
|
||||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SSMINE_SHIELD);
|
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SSMINE_SHIELD);
|
||||||
if (mo)
|
if (mo)
|
||||||
|
|
@ -9003,6 +9156,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mo->threshold = 10;
|
mo->threshold = 10;
|
||||||
mo->movecount = 1;
|
mo->movecount = 1;
|
||||||
mo->movedir = 1;
|
mo->movedir = 1;
|
||||||
|
mo->cusval = player->itemscale;
|
||||||
P_SetTarget(&mo->target, player->mo);
|
P_SetTarget(&mo->target, player->mo);
|
||||||
P_SetTarget(&player->mo->hnext, mo);
|
P_SetTarget(&player->mo->hnext, mo);
|
||||||
}
|
}
|
||||||
|
|
@ -9043,23 +9197,39 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
case KITEM_GROW:
|
case KITEM_GROW:
|
||||||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
||||||
{
|
{
|
||||||
if (player->growshrinktimer < 0) // If you're shrunk, then "grow" will just make you normal again.
|
if (player->growshrinktimer < 0)
|
||||||
|
{
|
||||||
|
// If you're shrunk, then "grow" will just make you normal again.
|
||||||
K_RemoveGrowShrink(player);
|
K_RemoveGrowShrink(player);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
K_PlayPowerGloatSound(player->mo);
|
K_PlayPowerGloatSound(player->mo);
|
||||||
|
|
||||||
player->mo->scalespeed = mapobjectscale/TICRATE;
|
player->mo->scalespeed = mapobjectscale/TICRATE;
|
||||||
player->mo->destscale = (3*mapobjectscale)/2;
|
player->mo->destscale = FixedMul(mapobjectscale, GROW_SCALE);
|
||||||
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
|
|
||||||
player->mo->destscale = (6*player->mo->destscale)/8;
|
if (K_PlayerShrinkCheat(player) == true)
|
||||||
|
{
|
||||||
|
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
player->growshrinktimer = itemtime+(4*TICRATE); // 12 seconds
|
player->growshrinktimer = itemtime+(4*TICRATE); // 12 seconds
|
||||||
if (P_IsLocalPlayer(player))
|
|
||||||
|
if (P_IsLocalPlayer(player) == true)
|
||||||
|
{
|
||||||
S_ChangeMusicSpecial("kgrow");
|
S_ChangeMusicSpecial("kgrow");
|
||||||
if (! P_IsDisplayPlayer(player))
|
}
|
||||||
|
|
||||||
|
if (P_IsDisplayPlayer(player) == false)
|
||||||
|
{
|
||||||
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow));
|
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow));
|
||||||
|
}
|
||||||
|
|
||||||
P_RestoreMusic(player);
|
P_RestoreMusic(player);
|
||||||
S_StartSound(player->mo, sfx_kc5a);
|
S_StartSound(player->mo, sfx_kc5a);
|
||||||
}
|
}
|
||||||
|
|
||||||
player->itemamount--;
|
player->itemamount--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -9236,7 +9406,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
|
||||||
{
|
{
|
||||||
mobj_t *mo;
|
mobj_t *mo;
|
||||||
player->pflags |= PF_ITEMOUT;
|
K_SetItemOut(player);
|
||||||
S_StartSound(player->mo, sfx_s254);
|
S_StartSound(player->mo, sfx_s254);
|
||||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SINK_SHIELD);
|
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SINK_SHIELD);
|
||||||
if (mo)
|
if (mo)
|
||||||
|
|
@ -9245,6 +9415,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
mo->threshold = 10;
|
mo->threshold = 10;
|
||||||
mo->movecount = 1;
|
mo->movecount = 1;
|
||||||
mo->movedir = 1;
|
mo->movedir = 1;
|
||||||
|
mo->cusval = player->itemscale;
|
||||||
P_SetTarget(&mo->target, player->mo);
|
P_SetTarget(&mo->target, player->mo);
|
||||||
P_SetTarget(&player->mo->hnext, mo);
|
P_SetTarget(&player->mo->hnext, mo);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
src/k_kart.h
13
src/k_kart.h
|
|
@ -22,6 +22,12 @@ Make sure this matches the actual number of states
|
||||||
#define MAXHITLAGTICS 18 //12
|
#define MAXHITLAGTICS 18 //12
|
||||||
#define HITLAGJITTERS (FRACUNIT / 20)
|
#define HITLAGJITTERS (FRACUNIT / 20)
|
||||||
|
|
||||||
|
#define GROW_SCALE (2*FRACUNIT)
|
||||||
|
#define SHRINK_SCALE (FRACUNIT/2)
|
||||||
|
|
||||||
|
#define GROW_PHYSICS_SCALE (3*FRACUNIT/2)
|
||||||
|
#define SHRINK_PHYSICS_SCALE (3*FRACUNIT/4)
|
||||||
|
|
||||||
player_t *K_GetItemBoxPlayer(mobj_t *mobj);
|
player_t *K_GetItemBoxPlayer(mobj_t *mobj);
|
||||||
angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed);
|
angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed);
|
||||||
|
|
||||||
|
|
@ -115,10 +121,13 @@ boolean K_WaterRun(player_t *player);
|
||||||
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
|
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
|
||||||
INT16 K_GetSpindashChargeTime(player_t *player);
|
INT16 K_GetSpindashChargeTime(player_t *player);
|
||||||
fixed_t K_GetSpindashChargeSpeed(player_t *player);
|
fixed_t K_GetSpindashChargeSpeed(player_t *player);
|
||||||
|
fixed_t K_GrowShrinkSpeedMul(player_t *player);
|
||||||
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
|
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
|
||||||
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
|
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower);
|
||||||
fixed_t K_GetKartAccel(player_t *player);
|
fixed_t K_GetKartAccel(player_t *player);
|
||||||
UINT16 K_GetKartFlashing(player_t *player);
|
UINT16 K_GetKartFlashing(player_t *player);
|
||||||
|
boolean K_PlayerShrinkCheat(player_t *player);
|
||||||
|
void K_UpdateShrinkCheat(player_t *player);
|
||||||
boolean K_KartKickstart(player_t *player);
|
boolean K_KartKickstart(player_t *player);
|
||||||
UINT16 K_GetKartButtons(player_t *player);
|
UINT16 K_GetKartButtons(player_t *player);
|
||||||
SINT8 K_GetForwardMove(player_t *player);
|
SINT8 K_GetForwardMove(player_t *player);
|
||||||
|
|
@ -141,5 +150,9 @@ void K_PlayPainSound(mobj_t *source);
|
||||||
void K_PlayHitEmSound(mobj_t *source);
|
void K_PlayHitEmSound(mobj_t *source);
|
||||||
void K_PlayPowerGloatSound(mobj_t *source);
|
void K_PlayPowerGloatSound(mobj_t *source);
|
||||||
|
|
||||||
|
fixed_t K_ItemScaleForPlayer(player_t *player);
|
||||||
|
void K_SetItemOut(player_t *player);
|
||||||
|
void K_UnsetItemOut(player_t *player);
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
#endif // __K_KART__
|
#endif // __K_KART__
|
||||||
|
|
|
||||||
|
|
@ -672,11 +672,11 @@ static void K_HandleDropDash(player_t *player)
|
||||||
if (player->growshrinktimer < 0)
|
if (player->growshrinktimer < 0)
|
||||||
{
|
{
|
||||||
player->mo->scalespeed = mapobjectscale/TICRATE;
|
player->mo->scalespeed = mapobjectscale/TICRATE;
|
||||||
player->mo->destscale = (6*mapobjectscale)/8;
|
player->mo->destscale = FixedMul(mapobjectscale, SHRINK_SCALE);
|
||||||
|
|
||||||
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
|
if (K_PlayerShrinkCheat(player) == true)
|
||||||
{
|
{
|
||||||
player->mo->destscale = (6*player->mo->destscale)/8;
|
player->mo->destscale = FixedMul(player->mo->destscale, SHRINK_SCALE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14107,7 +14107,7 @@ void A_SSMineExplode(mobj_t *actor)
|
||||||
INT32 d;
|
INT32 d;
|
||||||
INT32 locvar1 = var1;
|
INT32 locvar1 = var1;
|
||||||
mobjtype_t type;
|
mobjtype_t type;
|
||||||
explodedist = FixedMul((3*actor->info->painchance)/2, mapobjectscale);
|
explodedist = FixedMul((3*actor->info->painchance)/2, actor->scale);
|
||||||
|
|
||||||
if (LUA_CallAction(A_SSMINEEXPLODE, actor))
|
if (LUA_CallAction(A_SSMINEEXPLODE, actor))
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1929,7 +1929,18 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
|
|
||||||
if (combo == false)
|
if (combo == false)
|
||||||
{
|
{
|
||||||
if (player->mo->hitlag == 0 && player->flashing > 0)
|
// Check if we should allow wombo combos (DMG_WOMBO)
|
||||||
|
boolean allowcombo = false;
|
||||||
|
|
||||||
|
// For MISSILE OBJECTS, allow combo BY DEFAULT. If DMG_WOMBO is set, do *NOT* allow it.
|
||||||
|
if (inflictor && !P_MobjWasRemoved(inflictor) && (inflictor->flags & MF_MISSILE) && !(damagetype & DMG_WOMBO))
|
||||||
|
allowcombo = true;
|
||||||
|
|
||||||
|
// OTHERWISE, only allow combos IF DMG_WOMBO *IS* set.
|
||||||
|
else if (damagetype & DMG_WOMBO)
|
||||||
|
allowcombo = true;
|
||||||
|
|
||||||
|
if ((player->mo->hitlag == 0 || allowcombo == false) && player->flashing > 0)
|
||||||
{
|
{
|
||||||
// Post-hit invincibility
|
// Post-hit invincibility
|
||||||
K_DoInstashield(player);
|
K_DoInstashield(player);
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ struct demofreecam_s {
|
||||||
|
|
||||||
camera_t *cam; // this is useful when the game is paused, notably
|
camera_t *cam; // this is useful when the game is paused, notably
|
||||||
mobj_t *soundmobj; // mobj to play sound from, used in s_sound
|
mobj_t *soundmobj; // mobj to play sound from, used in s_sound
|
||||||
|
|
||||||
angle_t localangle; // keeps track of the cam angle for cmds
|
angle_t localangle; // keeps track of the cam angle for cmds
|
||||||
angle_t localaiming; // ditto with aiming
|
angle_t localaiming; // ditto with aiming
|
||||||
boolean turnheld; // holding turn button for gradual turn speed
|
boolean turnheld; // holding turn button for gradual turn speed
|
||||||
|
|
@ -486,6 +486,7 @@ typedef struct BasicFF_s
|
||||||
#define DMG_SPECTATOR 0x83
|
#define DMG_SPECTATOR 0x83
|
||||||
#define DMG_TIMEOVER 0x84
|
#define DMG_TIMEOVER 0x84
|
||||||
// Masks
|
// Masks
|
||||||
|
#define DMG_WOMBO 0x10 // Flag - setting this flag allows objects to damage you if you're already in spinout. The effect is reversed on objects with MF_MISSILE (setting it prevents them from comboing in spinout)
|
||||||
#define DMG_STEAL 0x20 // Flag - can steal bumpers, will only deal damage to players, and will not deal damage outside Battle Mode.
|
#define DMG_STEAL 0x20 // Flag - can steal bumpers, will only deal damage to players, and will not deal damage outside Battle Mode.
|
||||||
#define DMG_CANTHURTSELF 0x40 // Flag - cannot hurt your self or your team
|
#define DMG_CANTHURTSELF 0x40 // Flag - cannot hurt your self or your team
|
||||||
#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type
|
#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type
|
||||||
|
|
|
||||||
|
|
@ -782,7 +782,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Player Damage
|
// Player Damage
|
||||||
P_DamageMobj(tmthing, ((thing->type == MT_BUBBLESHIELD) ? thing->target : thing), thing, 1, DMG_NORMAL);
|
P_DamageMobj(tmthing, ((thing->type == MT_BUBBLESHIELD) ? thing->target : thing), thing, 1, DMG_NORMAL|DMG_WOMBO);
|
||||||
S_StartSound(thing, sfx_s3k44);
|
S_StartSound(thing, sfx_s3k44);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -10874,9 +10874,12 @@ void P_SpawnPlayer(INT32 playernum)
|
||||||
|
|
||||||
P_SetTarget(&p->follower, NULL); // cleanse follower from existence
|
P_SetTarget(&p->follower, NULL); // cleanse follower from existence
|
||||||
|
|
||||||
|
if (K_PlayerShrinkCheat(p) == true)
|
||||||
|
{
|
||||||
|
mobj->destscale = FixedMul(mobj->destscale, SHRINK_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
// set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't.
|
// set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't.
|
||||||
if (cv_kartdebugshrink.value && !modeattacking && !p->bot)
|
|
||||||
mobj->destscale = 6*mobj->destscale/8;
|
|
||||||
P_SetScale(mobj, mobj->destscale);
|
P_SetScale(mobj, mobj->destscale);
|
||||||
P_FlashPal(p, 0, 0); // Resets
|
P_FlashPal(p, 0, 0); // Resets
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,9 @@ typedef enum
|
||||||
MF_PICKUPFROMBELOW = 1<<29,
|
MF_PICKUPFROMBELOW = 1<<29,
|
||||||
// Disable momentum-based squash and stretch.
|
// Disable momentum-based squash and stretch.
|
||||||
MF_NOSQUISH = 1<<30,
|
MF_NOSQUISH = 1<<30,
|
||||||
// free: to and including 1<<31
|
// Disable hitlag for this object
|
||||||
|
MF_NOHITLAGFORME = 1<<31,
|
||||||
|
// no more free slots, next up I suppose we can get rid of shit like MF_BOXICON?
|
||||||
} mobjflag_t;
|
} mobjflag_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "k_terrain.h" // TRF_TRIPWIRE
|
#include "k_terrain.h" // TRF_TRIPWIRE
|
||||||
#include "k_brightmap.h"
|
#include "k_brightmap.h"
|
||||||
|
#include "k_director.h" // K_InitDirector
|
||||||
|
|
||||||
// Replay names have time
|
// Replay names have time
|
||||||
#if !defined (UNDER_CE)
|
#if !defined (UNDER_CE)
|
||||||
|
|
@ -1939,6 +1940,70 @@ static void P_LoadTextmap(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fixed_t
|
||||||
|
P_MirrorTextureOffset
|
||||||
|
( fixed_t offset,
|
||||||
|
fixed_t source_width,
|
||||||
|
fixed_t actual_width)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Adjusting the horizontal alignment is a bit ASS...
|
||||||
|
Textures on the opposite side of the line will begin
|
||||||
|
drawing from the opposite end.
|
||||||
|
|
||||||
|
Start with the texture width and subtract the seg
|
||||||
|
length to account for cropping/wrapping. Subtract the
|
||||||
|
offset to mirror the alignment.
|
||||||
|
*/
|
||||||
|
return source_width - actual_width - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean P_CheckLineSideTripWire(line_t *ld, int p)
|
||||||
|
{
|
||||||
|
INT32 n;
|
||||||
|
|
||||||
|
side_t *sda;
|
||||||
|
side_t *sdb;
|
||||||
|
|
||||||
|
terrain_t *terrain;
|
||||||
|
|
||||||
|
boolean tripwire;
|
||||||
|
|
||||||
|
n = ld->sidenum[p];
|
||||||
|
|
||||||
|
if (n == 0xffff)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sda = &sides[n];
|
||||||
|
|
||||||
|
terrain = K_GetTerrainForTextureNum(sda->midtexture);
|
||||||
|
tripwire = terrain && (terrain->flags & TRF_TRIPWIRE);
|
||||||
|
|
||||||
|
if (tripwire)
|
||||||
|
{
|
||||||
|
// copy midtexture to other side
|
||||||
|
n = ld->sidenum[!p];
|
||||||
|
|
||||||
|
if (n != 0xffff)
|
||||||
|
{
|
||||||
|
fixed_t linelength = FixedHypot(ld->dx, ld->dy);
|
||||||
|
texture_t *tex = textures[sda->midtexture];
|
||||||
|
|
||||||
|
sdb = &sides[n];
|
||||||
|
|
||||||
|
sdb->midtexture = sda->midtexture;
|
||||||
|
sdb->rowoffset = sda->rowoffset;
|
||||||
|
|
||||||
|
// mirror texture alignment
|
||||||
|
sdb->textureoffset = P_MirrorTextureOffset(
|
||||||
|
sda->textureoffset, tex->width * FRACUNIT,
|
||||||
|
linelength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tripwire;
|
||||||
|
}
|
||||||
|
|
||||||
static void P_ProcessLinedefsAfterSidedefs(void)
|
static void P_ProcessLinedefsAfterSidedefs(void)
|
||||||
{
|
{
|
||||||
size_t i = numlines;
|
size_t i = numlines;
|
||||||
|
|
@ -1946,16 +2011,14 @@ static void P_ProcessLinedefsAfterSidedefs(void)
|
||||||
|
|
||||||
for (; i--; ld++)
|
for (; i--; ld++)
|
||||||
{
|
{
|
||||||
INT32 midtexture = sides[ld->sidenum[0]].midtexture;
|
|
||||||
terrain_t *terrain = K_GetTerrainForTextureNum(midtexture);
|
|
||||||
|
|
||||||
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
|
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
|
||||||
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
|
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
|
||||||
|
|
||||||
if (terrain != NULL && (terrain->flags & TRF_TRIPWIRE))
|
// Check for tripwire, if either side matches then
|
||||||
{
|
// copy that (mid)texture to the other side.
|
||||||
ld->tripwire = true;
|
ld->tripwire =
|
||||||
}
|
P_CheckLineSideTripWire(ld, 0) ||
|
||||||
|
P_CheckLineSideTripWire(ld, 1);
|
||||||
|
|
||||||
switch (ld->special)
|
switch (ld->special)
|
||||||
{
|
{
|
||||||
|
|
@ -3465,6 +3528,7 @@ static void P_InitLevelSettings(void)
|
||||||
players[i].lives = 3;
|
players[i].lives = 3;
|
||||||
|
|
||||||
G_PlayerReborn(i, true);
|
G_PlayerReborn(i, true);
|
||||||
|
K_UpdateShrinkCheat(&players[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
racecountdown = exitcountdown = exitfadestarted = 0;
|
racecountdown = exitcountdown = exitfadestarted = 0;
|
||||||
|
|
@ -4142,6 +4206,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||||
memset(localaiming, 0, sizeof(localaiming));
|
memset(localaiming, 0, sizeof(localaiming));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
K_InitDirector();
|
||||||
|
|
||||||
wantedcalcdelay = wantedfrequency*2;
|
wantedcalcdelay = wantedfrequency*2;
|
||||||
indirectitemcooldown = 0;
|
indirectitemcooldown = 0;
|
||||||
hyubgone = 0;
|
hyubgone = 0;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#include "k_race.h"
|
#include "k_race.h"
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_waypoint.h"
|
#include "k_waypoint.h"
|
||||||
|
#include "k_director.h"
|
||||||
|
|
||||||
tic_t leveltime;
|
tic_t leveltime;
|
||||||
|
|
||||||
|
|
@ -706,6 +707,8 @@ void P_Ticker(boolean run)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
K_UpdateDirector();
|
||||||
|
|
||||||
// Always move the camera.
|
// Always move the camera.
|
||||||
for (i = 0; i <= r_splitscreen; i++)
|
for (i = 0; i <= r_splitscreen; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2464,8 +2464,10 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
||||||
indirectitemcooldown = 0;
|
indirectitemcooldown = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players!
|
if (mo->flags & MF_BOSS) //don't OHKO bosses nor players!
|
||||||
P_DamageMobj(mo, inflictor, source, 1, DMG_NORMAL|DMG_CANTHURTSELF);
|
P_DamageMobj(mo, inflictor, source, 1, DMG_NORMAL|DMG_CANTHURTSELF);
|
||||||
|
else if (mo->type == MT_PLAYER) // Thunder shield: Combo players.
|
||||||
|
P_DamageMobj(mo, inflictor, source, 1, DMG_NORMAL|DMG_CANTHURTSELF|DMG_WOMBO);
|
||||||
else
|
else
|
||||||
P_DamageMobj(mo, inflictor, source, 1000, DMG_NORMAL|DMG_CANTHURTSELF);
|
P_DamageMobj(mo, inflictor, source, 1000, DMG_NORMAL|DMG_CANTHURTSELF);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -861,7 +861,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
|
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
|
||||||
R_SetColumnFunc(COLDRAWFUNC_TRANS, false);
|
R_SetColumnFunc(COLDRAWFUNC_TRANS, false);
|
||||||
|
|
||||||
if (vis->extra_colormap && !(vis->renderflags & RF_NOCOLORMAPS))
|
if (vis->extra_colormap && !(vis->cut & SC_FULLBRIGHT) && !(vis->renderflags & RF_NOCOLORMAPS))
|
||||||
{
|
{
|
||||||
if (!dc_colormap)
|
if (!dc_colormap)
|
||||||
dc_colormap = vis->extra_colormap->colormap;
|
dc_colormap = vis->extra_colormap->colormap;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue