mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' into cheats-streamline
This commit is contained in:
commit
a60d48202f
40 changed files with 2293 additions and 1264 deletions
|
|
@ -49,15 +49,15 @@ jobs:
|
|||
paths:
|
||||
- /var/cache/apt/archives
|
||||
- checkout
|
||||
- run:
|
||||
name: Compile without network support
|
||||
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1
|
||||
- run:
|
||||
name: wipe build
|
||||
command: make -C src LINUX=1 cleandep
|
||||
- run:
|
||||
name: rebuild depend
|
||||
command: make -C src LINUX=1 clean
|
||||
#- run:
|
||||
# name: Compile without network support
|
||||
# command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1
|
||||
#- run:
|
||||
# name: wipe build
|
||||
# command: make -C src LINUX=1 cleandep
|
||||
#- run:
|
||||
# name: rebuild depend
|
||||
# command: make -C src LINUX=1 clean
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-SRB2-{{ .Branch }}-{{ checksum "objs/Linux/SDL/Release/depend.dep" }}
|
||||
|
|
|
|||
181
src/command.c
181
src/command.c
|
|
@ -1036,15 +1036,17 @@ static void COM_Help_f(void)
|
|||
|
||||
/** Toggles a console variable. Useful for on/off values.
|
||||
*
|
||||
* This works on on/off, yes/no values only
|
||||
* This works on on/off, yes/no values by default. Given
|
||||
* a list of values, cycles between them.
|
||||
*/
|
||||
static void COM_Toggle_f(void)
|
||||
{
|
||||
consvar_t *cvar;
|
||||
|
||||
if (COM_Argc() != 2)
|
||||
if (COM_Argc() == 1 || COM_Argc() == 3)
|
||||
{
|
||||
CONS_Printf(M_GetText("Toggle <cvar_name>: Toggle the value of a cvar\n"));
|
||||
CONS_Printf("Toggle <cvar_name> <value1> <value2>...: Cycle along a set of values\n");
|
||||
return;
|
||||
}
|
||||
cvar = CV_FindVar(COM_Argv(1));
|
||||
|
|
@ -1054,15 +1056,44 @@ static void COM_Toggle_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff))
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("%s is not a boolean value\n"), COM_Argv(1));
|
||||
return;
|
||||
if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("%s is not a boolean value\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// netcvar don't change imediately
|
||||
cvar->flags |= CV_SHOWMODIFONETIME;
|
||||
CV_AddValue(cvar, +1);
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
CV_AddValue(cvar, +1);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 2; i < COM_Argc() - 1; ++i)
|
||||
{
|
||||
const char *str = COM_Argv(i);
|
||||
INT32 val;
|
||||
|
||||
if (CV_CompleteValue(cvar, &str, &val))
|
||||
{
|
||||
if (str ? !stricmp(cvar->string, str)
|
||||
: cvar->value == val)
|
||||
{
|
||||
CV_Set(cvar, COM_Argv(i + 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CV_Set(cvar, COM_Argv(2));
|
||||
}
|
||||
}
|
||||
|
||||
/** Command variant of CV_AddValue
|
||||
|
|
@ -1436,25 +1467,27 @@ const char *CV_CompleteVar(char *partial, INT32 skips)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/** Sets a value to a variable with less checking. Only for internal use.
|
||||
*
|
||||
* \param var Variable to set.
|
||||
* \param valstr String value for the variable.
|
||||
*/
|
||||
static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
||||
boolean CV_CompleteValue(consvar_t *var, const char **valstrp, INT32 *intval)
|
||||
{
|
||||
boolean override = false;
|
||||
const char *valstr = *valstrp;
|
||||
|
||||
INT32 overrideval = 0;
|
||||
|
||||
if ((var->flags & CV_CHEAT) && CV_CheatsEnabled() == false)
|
||||
INT32 v;
|
||||
|
||||
if (var == &cv_forceskin)
|
||||
{
|
||||
// Enforce to default value without cheats.
|
||||
valstr = var->defaultvalue;
|
||||
v = R_SkinAvailable(valstr);
|
||||
|
||||
if (!R_SkinUsable(-1, v))
|
||||
v = -1;
|
||||
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (var->PossibleValue)
|
||||
{
|
||||
INT32 v;
|
||||
INT32 i;
|
||||
|
||||
if (var->flags & CV_FLOAT)
|
||||
{
|
||||
|
|
@ -1475,7 +1508,6 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
|||
{
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
INT32 i;
|
||||
#ifdef PARANOIA
|
||||
if (!var->PossibleValue[MAXVAL].strvalue)
|
||||
I_Error("Bounded cvar \"%s\" without maximum!\n", var->name);
|
||||
|
|
@ -1484,52 +1516,26 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
|||
// search for other
|
||||
for (i = MAXVAL+1; var->PossibleValue[i].strvalue; i++)
|
||||
if (v == var->PossibleValue[i].value || !stricmp(var->PossibleValue[i].strvalue, valstr))
|
||||
{
|
||||
if (client && execversion_enabled)
|
||||
{
|
||||
if (var->revert.allocated)
|
||||
{
|
||||
Z_Free(var->revert.v.string);
|
||||
var->revert.allocated = false; // the below value is not allocated in zone memory, don't try to free it!
|
||||
}
|
||||
|
||||
var->revert.v.const_munge = var->PossibleValue[i].strvalue;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// free the old value string
|
||||
Z_Free(var->zstring);
|
||||
var->zstring = NULL;
|
||||
|
||||
var->value = var->PossibleValue[i].value;
|
||||
var->string = var->PossibleValue[i].strvalue;
|
||||
goto finish;
|
||||
}
|
||||
goto found;
|
||||
|
||||
if ((v != INT32_MIN && v < var->PossibleValue[MINVAL].value) || !stricmp(valstr, "MIN"))
|
||||
{
|
||||
v = var->PossibleValue[MINVAL].value;
|
||||
valstr = var->PossibleValue[MINVAL].strvalue;
|
||||
override = true;
|
||||
overrideval = v;
|
||||
i = MINVAL;
|
||||
goto found;
|
||||
}
|
||||
else if ((v != INT32_MIN && v > var->PossibleValue[MAXVAL].value) || !stricmp(valstr, "MAX"))
|
||||
{
|
||||
v = var->PossibleValue[MAXVAL].value;
|
||||
valstr = var->PossibleValue[MAXVAL].strvalue;
|
||||
override = true;
|
||||
overrideval = v;
|
||||
i = MAXVAL;
|
||||
goto found;
|
||||
}
|
||||
if (v == INT32_MIN)
|
||||
goto badinput;
|
||||
valstr = NULL; // not a preset value
|
||||
#undef MINVAL
|
||||
#undef MAXVAL
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
// check first strings
|
||||
for (i = 0; var->PossibleValue[i].strvalue; i++)
|
||||
if (!stricmp(var->PossibleValue[i].strvalue, valstr))
|
||||
|
|
@ -1561,27 +1567,66 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
|||
// ...or not.
|
||||
goto badinput;
|
||||
found:
|
||||
if (client && execversion_enabled)
|
||||
{
|
||||
var->revert.v.const_munge = var->PossibleValue[i].strvalue;
|
||||
return;
|
||||
}
|
||||
v = var->PossibleValue[i].value;
|
||||
valstr = var->PossibleValue[i].strvalue;
|
||||
}
|
||||
|
||||
var->value = var->PossibleValue[i].value;
|
||||
var->string = var->PossibleValue[i].strvalue;
|
||||
goto finish;
|
||||
finish:
|
||||
if (intval)
|
||||
*intval = v;
|
||||
|
||||
*valstrp = valstr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// landing point for possiblevalue failures
|
||||
badinput:
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Sets a value to a variable with less checking. Only for internal use.
|
||||
*
|
||||
* \param var Variable to set.
|
||||
* \param valstr String value for the variable.
|
||||
*/
|
||||
static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
|
||||
{
|
||||
boolean override = false;
|
||||
INT32 overrideval = 0;
|
||||
const char *overridestr = valstr;
|
||||
|
||||
if ((var->flags & CV_CHEAT) && CV_CheatsEnabled() == false)
|
||||
{
|
||||
// Enforce to default value without cheats.
|
||||
overridestr = var->defaultvalue;
|
||||
}
|
||||
else if (CV_CompleteValue(var, &overridestr, &overrideval))
|
||||
{
|
||||
if (overridestr)
|
||||
{
|
||||
valstr = overridestr;
|
||||
override = true;
|
||||
}
|
||||
}
|
||||
else if (var->PossibleValue)
|
||||
goto badinput;
|
||||
|
||||
if (client && execversion_enabled)
|
||||
{
|
||||
if (var->revert.allocated)
|
||||
{
|
||||
Z_Free(var->revert.v.string);
|
||||
|
||||
// Z_StrDup creates a new zone memory block, so we can keep the allocated flag on
|
||||
if (override)
|
||||
var->revert.allocated = false; // the below value is not allocated in zone memory, don't try to free it!
|
||||
}
|
||||
|
||||
var->revert.v.string = Z_StrDup(valstr);
|
||||
if (override)
|
||||
var->revert.v.const_munge = valstr;
|
||||
else
|
||||
var->revert.v.string = Z_StrDup(valstr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -1589,22 +1634,20 @@ found:
|
|||
// free the old value string
|
||||
Z_Free(var->zstring);
|
||||
|
||||
var->string = var->zstring = Z_StrDup(valstr);
|
||||
|
||||
if (override)
|
||||
var->value = overrideval;
|
||||
else if (var->flags & CV_FLOAT)
|
||||
{
|
||||
double d = atof(var->string);
|
||||
var->value = (INT32)(d * FRACUNIT);
|
||||
var->zstring = NULL;
|
||||
var->value = overrideval;
|
||||
var->string = valstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (var == &cv_forceskin)
|
||||
var->string = var->zstring = Z_StrDup(valstr);
|
||||
|
||||
if (var->flags & CV_FLOAT)
|
||||
{
|
||||
var->value = R_SkinAvailable(var->string);
|
||||
if (!R_SkinUsable(-1, var->value))
|
||||
var->value = -1;
|
||||
double d = atof(var->string);
|
||||
var->value = (INT32)(d * FRACUNIT);
|
||||
}
|
||||
else
|
||||
var->value = atoi(var->string);
|
||||
|
|
|
|||
|
|
@ -194,6 +194,12 @@ void CV_ClearChangedFlags(void);
|
|||
// returns the name of the nearest console variable name found
|
||||
const char *CV_CompleteVar(char *partial, INT32 skips);
|
||||
|
||||
// Returns true if valstrp is within the PossibleValues of
|
||||
// var. If an exact string value exists, it is returned in
|
||||
// valstrp. An integer value is returned in intval if it
|
||||
// is not NULL.
|
||||
boolean CV_CompleteValue(consvar_t *var, const char **valstrp, INT32 *intval);
|
||||
|
||||
// equivalent to "<varname> <value>" typed at the console
|
||||
void CV_Set(consvar_t *var, const char *value);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,11 +58,11 @@ typedef enum
|
|||
//
|
||||
typedef enum
|
||||
{
|
||||
// True if button down last tic.
|
||||
PF_ATTACKDOWN = 1,
|
||||
PF_ACCELDOWN = 1<<1,
|
||||
PF_BRAKEDOWN = 1<<2,
|
||||
PF_LOOKDOWN = 1<<3,
|
||||
// free: 1<<0 to 1<<2
|
||||
|
||||
// Look back VFX has been spawned
|
||||
// TODO: Is there a better way to track this?
|
||||
PF_GAINAX = 1<<3,
|
||||
|
||||
// Accessibility and cheats
|
||||
PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode?
|
||||
|
|
@ -337,6 +337,7 @@ typedef struct player_s
|
|||
|
||||
// Caveat: ticcmd_t is ATTRPACK! Be careful what precedes it.
|
||||
ticcmd_t cmd;
|
||||
ticcmd_t oldcmd; // from the previous tic
|
||||
|
||||
playerstate_t playerstate;
|
||||
|
||||
|
|
@ -435,6 +436,9 @@ typedef struct player_s
|
|||
UINT8 driftboost; // (0 to 125) - Boost you get from drifting
|
||||
UINT8 strongdriftboost; // (0 to 125) - While active, boost from drifting gives a stronger speed increase
|
||||
|
||||
UINT16 gateBoost; // Juicebox Manta Ring boosts
|
||||
UINT8 gateSound; // Sound effect combo
|
||||
|
||||
SINT8 aizdriftstrat; // (-1 to 1) - Let go of your drift while boosting? Helper for the SICK STRATZ (sliptiding!) you have just unlocked
|
||||
INT32 aizdrifttilt;
|
||||
INT32 aizdriftturn;
|
||||
|
|
|
|||
|
|
@ -322,7 +322,6 @@ actionpointer_t actionpointers[] =
|
|||
{{A_ItemPop}, "A_ITEMPOP"},
|
||||
{{A_JawzChase}, "A_JAWZCHASE"},
|
||||
{{A_JawzExplode}, "A_JAWZEXPLODE"},
|
||||
{{A_SPBChase}, "A_SPBCHASE"},
|
||||
{{A_SSMineSearch}, "A_SSMINESEARCH"},
|
||||
{{A_SSMineExplode}, "A_SSMINEEXPLODE"},
|
||||
{{A_LandMineExplode}, "A_LANDMINEEXPLODE"},
|
||||
|
|
@ -3652,6 +3651,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_SPB20",
|
||||
"S_SPB_DEAD",
|
||||
|
||||
// Juicebox for SPB
|
||||
"S_MANTA1",
|
||||
"S_MANTA2",
|
||||
|
||||
// Lightning Shield
|
||||
"S_LIGHTNINGSHIELD1",
|
||||
"S_LIGHTNINGSHIELD2",
|
||||
|
|
@ -5356,6 +5359,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
|
||||
"MT_SPB", // Self-Propelled Bomb
|
||||
"MT_SPBEXPLOSION",
|
||||
"MT_MANTARING", // Juicebox for SPB
|
||||
|
||||
"MT_LIGHTNINGSHIELD", // Shields
|
||||
"MT_BUBBLESHIELD",
|
||||
|
|
@ -5725,11 +5729,14 @@ const char *const MAPTHINGFLAG_LIST[4] = {
|
|||
};
|
||||
|
||||
const char *const PLAYERFLAG_LIST[] = {
|
||||
// True if button down last tic.
|
||||
"ATTACKDOWN",
|
||||
"ACCELDOWN",
|
||||
"BRAKEDOWN",
|
||||
"LOOKDOWN",
|
||||
// free: 1<<0 to 1<<2 (name un-matchable)
|
||||
"\x01",
|
||||
"\x01",
|
||||
"\x01",
|
||||
|
||||
// Look back VFX has been spawned
|
||||
// TODO: Is there a better way to track this?
|
||||
"GAINAX",
|
||||
|
||||
// Accessibility and cheats
|
||||
"KICKSTARTACCEL", // Is accelerate in kickstart mode?
|
||||
|
|
|
|||
|
|
@ -706,7 +706,7 @@ extern boolean comeback;
|
|||
|
||||
extern SINT8 battlewanted[4];
|
||||
extern tic_t wantedcalcdelay;
|
||||
extern tic_t indirectitemcooldown;
|
||||
extern tic_t itemCooldowns[NUMKARTITEMS - 1];
|
||||
extern tic_t mapreset;
|
||||
extern boolean thwompsactive;
|
||||
extern UINT8 lastLowestLap;
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ SINT8 pickedvote; // What vote the host rolls
|
|||
// Server-sided, synched variables
|
||||
SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points
|
||||
tic_t wantedcalcdelay; // Time before it recalculates WANTED
|
||||
tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded
|
||||
tic_t itemCooldowns[NUMKARTITEMS - 1]; // Cooldowns to prevent item spawning
|
||||
tic_t mapreset; // Map reset delay when enough players have joined an empty game
|
||||
boolean thwompsactive; // Thwomps activate on lap 2
|
||||
UINT8 lastLowestLap; // Last lowest lap, for activating race lap executors
|
||||
|
|
@ -2428,11 +2428,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
// ^ Not necessary anyway since it will be respawned regardless considering it doesn't exist anymore.
|
||||
|
||||
|
||||
// Don't do anything immediately
|
||||
p->pflags |= PF_BRAKEDOWN;
|
||||
p->pflags |= PF_ATTACKDOWN;
|
||||
p->pflags |= PF_ACCELDOWN;
|
||||
|
||||
p->playerstate = PST_LIVE;
|
||||
p->panim = PA_STILL; // standing animation
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "../p_local.h" // stplyr
|
||||
#include "../g_game.h" // players
|
||||
#include "../k_hud.h"
|
||||
#include "../r_plane.h" // R_FlatDimensionsFromLumpSize
|
||||
|
||||
#include <fcntl.h>
|
||||
#include "../i_video.h" // for rendermode != render_glide
|
||||
|
|
@ -482,42 +483,17 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
|
|||
// --------------------------------------------------------------------------
|
||||
void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum)
|
||||
{
|
||||
FOutVector v[4];
|
||||
double dflatsize;
|
||||
INT32 flatflag;
|
||||
const size_t len = W_LumpLength(flatlumpnum);
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
dflatsize = 2048.0f;
|
||||
flatflag = 2047;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
dflatsize = 1024.0f;
|
||||
flatflag = 1023;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
dflatsize = 512.0f;
|
||||
flatflag = 511;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
dflatsize = 256.0f;
|
||||
flatflag = 255;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
dflatsize = 128.0f;
|
||||
flatflag = 127;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
dflatsize = 32.0f;
|
||||
flatflag = 31;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
dflatsize = 64.0f;
|
||||
flatflag = 63;
|
||||
break;
|
||||
}
|
||||
size_t sflatsize;
|
||||
double dflatsize;
|
||||
INT32 flatflag;
|
||||
|
||||
FOutVector v[4];
|
||||
|
||||
sflatsize = R_FlatDimensionsFromLumpSize(len);
|
||||
dflatsize = (double)sflatsize;
|
||||
flatflag = sflatsize - 1;
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
// SRB2Kart
|
||||
#include "../k_kart.h" // HITLAGJITTERS
|
||||
#include "../r_fps.h"
|
||||
#include "../r_plane.h" // R_FlatDimensionsFromLumpSize
|
||||
|
||||
#ifdef NEWCLIP
|
||||
#include "hw_clip.h"
|
||||
|
|
@ -393,31 +394,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
|||
if (levelflat->type == LEVELFLAT_FLAT)
|
||||
{
|
||||
size_t len = W_LumpLength(levelflat->u.flat.lumpnum);
|
||||
switch (len)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
fflatwidth = fflatheight = 2048.0f;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
fflatwidth = fflatheight = 1024.0f;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
fflatwidth = fflatheight = 512.0f;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
fflatwidth = fflatheight = 256.0f;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
fflatwidth = fflatheight = 128.0f;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
fflatwidth = fflatheight = 32.0f;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
fflatwidth = fflatheight = 64.0f;
|
||||
break;
|
||||
}
|
||||
flatflag = ((INT32)fflatwidth)-1;
|
||||
size_t sflatsize = R_FlatDimensionsFromLumpSize(len);
|
||||
fflatwidth = fflatheight = (double)sflatsize;
|
||||
flatflag = sflatsize-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2756,31 +2735,9 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
if (levelflat->type == LEVELFLAT_FLAT)
|
||||
{
|
||||
size_t len = W_LumpLength(levelflat->u.flat.lumpnum);
|
||||
switch (len)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
fflatwidth = fflatheight = 2048.0f;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
fflatwidth = fflatheight = 1024.0f;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
fflatwidth = fflatheight = 512.0f;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
fflatwidth = fflatheight = 256.0f;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
fflatwidth = fflatheight = 128.0f;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
fflatwidth = fflatheight = 32.0f;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
fflatwidth = fflatheight = 64.0f;
|
||||
break;
|
||||
}
|
||||
flatflag = ((INT32)fflatwidth)-1;
|
||||
size_t sflatsize = R_FlatDimensionsFromLumpSize(len);
|
||||
fflatwidth = fflatheight = (double)sflatsize;
|
||||
flatflag = sflatsize-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
78
src/info.c
78
src/info.c
|
|
@ -565,6 +565,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"BHOG", // Ballhog
|
||||
"BHBM", // Ballhog BOOM
|
||||
"SPBM", // Self-Propelled Bomb
|
||||
"TRIS", // SPB Manta Ring start
|
||||
"TRNQ", // SPB Manta Ring loop
|
||||
"THNS", // Lightning Shield
|
||||
"BUBS", // Bubble Shield (not Bubs)
|
||||
"BWVE", // Bubble Shield waves
|
||||
|
|
@ -4199,28 +4201,31 @@ state_t states[NUMSTATES] =
|
|||
{SPR_BHBM, FF_FULLBRIGHT|14, 1, {NULL}, 0, 0, S_BALLHOGBOOM16}, // S_BALLHOGBOOM15
|
||||
{SPR_BHBM, FF_FULLBRIGHT|15, 1, {NULL}, 0, 0, S_NULL}, // S_BALLHOGBOOM16
|
||||
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB2}, // S_SPB1
|
||||
{SPR_SPBM, 1, 1, {A_SPBChase}, 0, 0, S_SPB3}, // S_SPB2
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB4}, // S_SPB3
|
||||
{SPR_SPBM, 2, 1, {A_SPBChase}, 0, 0, S_SPB5}, // S_SPB4
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB6}, // S_SPB5
|
||||
{SPR_SPBM, 3, 1, {A_SPBChase}, 0, 0, S_SPB7}, // S_SPB6
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB8}, // S_SPB7
|
||||
{SPR_SPBM, 4, 1, {A_SPBChase}, 0, 0, S_SPB9}, // S_SPB8
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB10}, // S_SPB9
|
||||
{SPR_SPBM, 5, 1, {A_SPBChase}, 0, 0, S_SPB11}, // S_SPB10
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB12}, // S_SPB11
|
||||
{SPR_SPBM, 6, 1, {A_SPBChase}, 0, 0, S_SPB13}, // S_SPB12
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB14}, // S_SPB13
|
||||
{SPR_SPBM, 7, 1, {A_SPBChase}, 0, 0, S_SPB15}, // S_SPB14
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB16}, // S_SPB15
|
||||
{SPR_SPBM, 8, 1, {A_SPBChase}, 0, 0, S_SPB17}, // S_SPB16
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB18}, // S_SPB17
|
||||
{SPR_SPBM, 8, 1, {A_SPBChase}, 0, 0, S_SPB19}, // S_SPB18
|
||||
{SPR_SPBM, 0, 1, {A_SPBChase}, 0, 0, S_SPB20}, // S_SPB19
|
||||
{SPR_SPBM, 8, 1, {A_SPBChase}, 0, 0, S_SPB1}, // S_SPB20
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB2}, // S_SPB1
|
||||
{SPR_SPBM, 1, 1, {NULL}, 0, 0, S_SPB3}, // S_SPB2
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB4}, // S_SPB3
|
||||
{SPR_SPBM, 2, 1, {NULL}, 0, 0, S_SPB5}, // S_SPB4
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB6}, // S_SPB5
|
||||
{SPR_SPBM, 3, 1, {NULL}, 0, 0, S_SPB7}, // S_SPB6
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB8}, // S_SPB7
|
||||
{SPR_SPBM, 4, 1, {NULL}, 0, 0, S_SPB9}, // S_SPB8
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB10}, // S_SPB9
|
||||
{SPR_SPBM, 5, 1, {NULL}, 0, 0, S_SPB11}, // S_SPB10
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB12}, // S_SPB11
|
||||
{SPR_SPBM, 6, 1, {NULL}, 0, 0, S_SPB13}, // S_SPB12
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB14}, // S_SPB13
|
||||
{SPR_SPBM, 7, 1, {NULL}, 0, 0, S_SPB15}, // S_SPB14
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB16}, // S_SPB15
|
||||
{SPR_SPBM, 8, 1, {NULL}, 0, 0, S_SPB17}, // S_SPB16
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB18}, // S_SPB17
|
||||
{SPR_SPBM, 8, 1, {NULL}, 0, 0, S_SPB19}, // S_SPB18
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_SPB20}, // S_SPB19
|
||||
{SPR_SPBM, 8, 1, {NULL}, 0, 0, S_SPB1}, // S_SPB20
|
||||
{SPR_SPBM, 8, 175, {NULL}, 0, 0, S_NULL}, // S_SPB_DEAD
|
||||
|
||||
{SPR_TRIS, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|FF_ADD, 9, {NULL}, 2, 3, S_MANTA2}, // S_MANTA1
|
||||
{SPR_TRNQ, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|FF_ADD, -1, {NULL}, 7, 1, S_NULL}, // S_MANTA2
|
||||
|
||||
{SPR_THNS, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD2}, // S_LIGHTNINGSHIELD1
|
||||
{SPR_THNS, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD3}, // S_LIGHTNINGSHIELD2
|
||||
{SPR_THNS, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD4}, // S_LIGHTNINGSHIELD3
|
||||
|
|
@ -23906,6 +23911,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_MANTARING
|
||||
-1, // doomednum
|
||||
S_MANTA1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
64*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
0, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_LIGHTNINGSHIELD
|
||||
-1, // doomednum
|
||||
S_LIGHTNINGSHIELD1, // spawnstate
|
||||
|
|
@ -28704,13 +28736,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
16<<FRACBITS, // radius
|
||||
16<<FRACBITS, // radius
|
||||
32<<FRACBITS, // height
|
||||
1, // display offset
|
||||
100, // mass
|
||||
DMG_NORMAL, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_DONTENCOREMAP|MF_NOGRAVITY|MF_PAIN, // flags
|
||||
MF_NOGRAVITY|MF_PAIN|MF_NOHITLAGFORME|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -275,7 +275,6 @@ enum actionnum
|
|||
A_ITEMPOP,
|
||||
A_JAWZCHASE,
|
||||
A_JAWZEXPLODE,
|
||||
A_SPBCHASE,
|
||||
A_SSMINESEARCH,
|
||||
A_SSMINEEXPLODE,
|
||||
A_LANDMINEEXPLODE,
|
||||
|
|
@ -548,7 +547,6 @@ void A_ChangeHeight();
|
|||
void A_ItemPop();
|
||||
void A_JawzChase();
|
||||
void A_JawzExplode();
|
||||
void A_SPBChase();
|
||||
void A_SSMineSearch();
|
||||
void A_SSMineExplode();
|
||||
void A_LandMineExplode();
|
||||
|
|
@ -1113,6 +1111,8 @@ typedef enum sprite
|
|||
SPR_BHOG, // Ballhog
|
||||
SPR_BHBM, // Ballhog BOOM
|
||||
SPR_SPBM, // Self-Propelled Bomb
|
||||
SPR_TRIS, // SPB Manta Ring start
|
||||
SPR_TRNQ, // SPB Manta Ring loop
|
||||
SPR_THNS, // Thunder Shield
|
||||
SPR_BUBS, // Bubble Shield (not Bubs)
|
||||
SPR_BWVE, // Bubble Shield waves
|
||||
|
|
@ -4650,6 +4650,10 @@ typedef enum state
|
|||
S_SPB20,
|
||||
S_SPB_DEAD,
|
||||
|
||||
// Juicebox for SPB
|
||||
S_MANTA1,
|
||||
S_MANTA2,
|
||||
|
||||
// Thunder Shield
|
||||
S_LIGHTNINGSHIELD1,
|
||||
S_LIGHTNINGSHIELD2,
|
||||
|
|
@ -6390,6 +6394,7 @@ typedef enum mobj_type
|
|||
|
||||
MT_SPB, // SPB stuff
|
||||
MT_SPBEXPLOSION,
|
||||
MT_MANTARING, // Juicebox for SPB
|
||||
|
||||
MT_LIGHTNINGSHIELD, // Shields
|
||||
MT_BUBBLESHIELD,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,23 @@
|
|||
#include "m_random.h"
|
||||
#include "r_things.h" // numskins
|
||||
|
||||
/*--------------------------------------------------
|
||||
static inline boolean K_ItemButtonWasDown(player_t *player)
|
||||
|
||||
Looks for players around the bot, and presses the item button
|
||||
if there is one in range.
|
||||
|
||||
Input Arguments:-
|
||||
player - Bot to check.
|
||||
|
||||
Return:-
|
||||
true if the item button was pressed last tic, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
static inline boolean K_ItemButtonWasDown(player_t *player)
|
||||
{
|
||||
return (player->oldcmd.buttons & BT_ATTACK);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static boolean K_BotUseItemNearPlayer(player_t *player, ticcmd_t *cmd, fixed_t radius)
|
||||
|
||||
|
|
@ -45,7 +62,7 @@ static boolean K_BotUseItemNearPlayer(player_t *player, ticcmd_t *cmd, fixed_t r
|
|||
{
|
||||
UINT8 i;
|
||||
|
||||
if (player->pflags & PF_ATTACKDOWN)
|
||||
if (K_ItemButtonWasDown(player) == true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -327,7 +344,7 @@ static void K_ItemConfirmForTarget(player_t *bot, player_t *target, UINT16 amoun
|
|||
--------------------------------------------------*/
|
||||
static boolean K_BotGenericPressItem(player_t *player, ticcmd_t *cmd, SINT8 dir)
|
||||
{
|
||||
if (player->pflags & PF_ATTACKDOWN)
|
||||
if (K_ItemButtonWasDown(player) == true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -352,7 +369,7 @@ static boolean K_BotGenericPressItem(player_t *player, ticcmd_t *cmd, SINT8 dir)
|
|||
--------------------------------------------------*/
|
||||
static void K_BotItemGenericTap(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
if (!(player->pflags & PF_ATTACKDOWN))
|
||||
if (K_ItemButtonWasDown(player) == false)
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
player->botvars.itemconfirm = 0;
|
||||
|
|
@ -475,7 +492,7 @@ static void K_BotItemSneaker(player_t *player, ticcmd_t *cmd)
|
|||
|| player->speedboost > (FRACUNIT/8) // Have another type of boost (tethering)
|
||||
|| player->botvars.itemconfirm > 4*TICRATE) // Held onto it for too long
|
||||
{
|
||||
if (!player->sneakertimer && !(player->pflags & PF_ATTACKDOWN))
|
||||
if (player->sneakertimer == 0 && K_ItemButtonWasDown(player) == false)
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
player->botvars.itemconfirm = 2*TICRATE;
|
||||
|
|
@ -503,7 +520,7 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
if (player->botvars.itemconfirm > TICRATE)
|
||||
{
|
||||
if (!player->sneakertimer && !(player->pflags & PF_ATTACKDOWN))
|
||||
if (player->sneakertimer == 0 && K_ItemButtonWasDown(player) == false)
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
player->botvars.itemconfirm = 0;
|
||||
|
|
@ -1193,7 +1210,7 @@ static void K_BotItemRouletteMash(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
boolean mash = false;
|
||||
|
||||
if (player->pflags & PF_ATTACKDOWN)
|
||||
if (K_ItemButtonWasDown(player) == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
64
src/k_hud.c
64
src/k_hud.c
|
|
@ -695,7 +695,7 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny)
|
|||
}
|
||||
}
|
||||
|
||||
static patch_t **K_GetItemPatchTable(INT32 item)
|
||||
static patch_t *K_GetCachedItemPatch(INT32 item, UINT8 offset)
|
||||
{
|
||||
patch_t **kp[1 + NUMKARTITEMS] = {
|
||||
kp_sadface,
|
||||
|
|
@ -723,8 +723,8 @@ static patch_t **K_GetItemPatchTable(INT32 item)
|
|||
kp_droptarget,
|
||||
};
|
||||
|
||||
if (item >= KITEM_SAD && item < NUMKARTITEMS)
|
||||
return kp[item - KITEM_SAD];
|
||||
if (item == KITEM_SAD || (item > KITEM_NONE && item < NUMKARTITEMS))
|
||||
return kp[item - KITEM_SAD][offset];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1146,7 +1146,7 @@ static void K_drawKartItem(void)
|
|||
break;
|
||||
|
||||
default:
|
||||
localpatch = K_GetItemPatchTable(item)[offset];
|
||||
localpatch = K_GetCachedItemPatch(item, offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1224,7 +1224,7 @@ static void K_drawKartItem(void)
|
|||
/*FALLTHRU*/
|
||||
|
||||
default:
|
||||
localpatch = K_GetItemPatchTable(stplyr->itemtype)[offset];
|
||||
localpatch = K_GetCachedItemPatch(stplyr->itemtype, offset);
|
||||
|
||||
if (localpatch == NULL)
|
||||
localpatch = kp_nodraw; // diagnose underflows
|
||||
|
|
@ -4445,7 +4445,6 @@ static void K_drawDistributionDebugger(void)
|
|||
kp_jawz[1],
|
||||
kp_mine[1],
|
||||
kp_landmine[1],
|
||||
kp_droptarget[1],
|
||||
kp_ballhog[1],
|
||||
kp_selfpropelledbomb[1],
|
||||
kp_grow[1],
|
||||
|
|
@ -4457,6 +4456,7 @@ static void K_drawDistributionDebugger(void)
|
|||
kp_pogospring[1],
|
||||
kp_superring[1],
|
||||
kp_kitchensink[1],
|
||||
kp_droptarget[1],
|
||||
|
||||
kp_sneaker[1],
|
||||
kp_sneaker[1],
|
||||
|
|
@ -4471,11 +4471,17 @@ static void K_drawDistributionDebugger(void)
|
|||
UINT32 pdis = 0;
|
||||
INT32 i;
|
||||
INT32 x = -9, y = -9;
|
||||
boolean spbrush = false;
|
||||
|
||||
if (stplyr != &players[displayplayers[0]]) // only for p1
|
||||
return;
|
||||
|
||||
if (K_ForcedSPB(stplyr) == true)
|
||||
{
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOTOP, items[KITEM_SPB]);
|
||||
V_DrawThinString(x+11, y+31, V_ALLOWLOWERCASE|V_SNAPTOTOP, "EX");
|
||||
return;
|
||||
}
|
||||
|
||||
// The only code duplication from the Kart, just to avoid the actual item function from calculating pingame twice
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
|
@ -4498,14 +4504,7 @@ static void K_drawDistributionDebugger(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (spbplace != -1 && stplyr->position == spbplace+1)
|
||||
{
|
||||
// SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell
|
||||
pdis = (3 * pdis) / 2;
|
||||
spbrush = true;
|
||||
}
|
||||
|
||||
pdis = K_ScaleItemDistance(pdis, pingame, spbrush);
|
||||
pdis = K_ScaleItemDistance(pdis, pingame);
|
||||
|
||||
if (stplyr->bot && stplyr->botvars.rival)
|
||||
{
|
||||
|
|
@ -4513,7 +4512,7 @@ static void K_drawDistributionDebugger(void)
|
|||
pdis = (15 * pdis) / 14;
|
||||
}
|
||||
|
||||
useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper, spbrush);
|
||||
useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper);
|
||||
|
||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||
{
|
||||
|
|
@ -4521,38 +4520,21 @@ static void K_drawDistributionDebugger(void)
|
|||
useodds, i,
|
||||
stplyr->distancetofinish,
|
||||
0,
|
||||
spbrush, stplyr->bot, (stplyr->bot && stplyr->botvars.rival)
|
||||
stplyr->bot, (stplyr->bot && stplyr->botvars.rival)
|
||||
);
|
||||
INT32 amount = 1;
|
||||
|
||||
if (itemodds <= 0)
|
||||
continue;
|
||||
|
||||
V_DrawScaledPatch(x, y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP, items[i]);
|
||||
V_DrawThinString(x+11, y+31, V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP, va("%d", itemodds));
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOTOP, items[i]);
|
||||
V_DrawThinString(x+11, y+31, V_SNAPTOTOP, va("%d", itemodds));
|
||||
|
||||
// Display amount for multi-items
|
||||
if (i >= NUMKARTITEMS)
|
||||
amount = K_ItemResultToAmount(i);
|
||||
if (amount > 1)
|
||||
{
|
||||
INT32 amount;
|
||||
switch (i)
|
||||
{
|
||||
case KRITEM_TENFOLDBANANA:
|
||||
amount = 10;
|
||||
break;
|
||||
case KRITEM_QUADORBINAUT:
|
||||
amount = 4;
|
||||
break;
|
||||
case KRITEM_DUALJAWZ:
|
||||
amount = 2;
|
||||
break;
|
||||
case KRITEM_DUALSNEAKER:
|
||||
amount = 2;
|
||||
break;
|
||||
default:
|
||||
amount = 3;
|
||||
break;
|
||||
}
|
||||
V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP, va("x%d", amount));
|
||||
V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("x%d", amount));
|
||||
}
|
||||
|
||||
x += 32;
|
||||
|
|
@ -4563,7 +4545,7 @@ static void K_drawDistributionDebugger(void)
|
|||
}
|
||||
}
|
||||
|
||||
V_DrawString(0, 0, V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP, va("USEODDS %d", useodds));
|
||||
V_DrawString(0, 0, V_SNAPTOTOP, va("USEODDS %d", useodds));
|
||||
}
|
||||
|
||||
static void K_drawCheckpointDebugger(void)
|
||||
|
|
|
|||
659
src/k_kart.c
659
src/k_kart.c
File diff suppressed because it is too large
Load diff
16
src/k_kart.h
16
src/k_kart.h
|
|
@ -44,12 +44,18 @@ fixed_t K_GetKartGameSpeedScalar(SINT8 value);
|
|||
|
||||
extern consvar_t *KartItemCVars[NUMKARTRESULTS-1];
|
||||
|
||||
UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper, boolean spbrush);
|
||||
fixed_t K_ItemOddsScale(UINT8 numPlayers, boolean spbrush);
|
||||
UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers, boolean spbrush);
|
||||
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, fixed_t mashed, boolean spbrush, boolean bot, boolean rival);
|
||||
UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper);
|
||||
fixed_t K_ItemOddsScale(UINT8 numPlayers);
|
||||
UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers);
|
||||
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, fixed_t mashed, boolean bot, boolean rival);
|
||||
INT32 K_GetRollingRouletteItem(player_t *player);
|
||||
boolean K_ForcedSPB(player_t *player);
|
||||
INT32 K_GetShieldFromItem(INT32 item);
|
||||
SINT8 K_ItemResultToType(SINT8 getitem);
|
||||
UINT8 K_ItemResultToAmount(SINT8 getitem);
|
||||
tic_t K_GetItemCooldown(SINT8 itemResult);
|
||||
void K_SetItemCooldown(SINT8 itemResult, tic_t time);
|
||||
void K_RunItemCooldowns(void);
|
||||
fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against);
|
||||
boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2);
|
||||
boolean K_KartSolidBounce(mobj_t *bounceMobj, mobj_t *solidMobj);
|
||||
|
|
@ -119,7 +125,7 @@ INT32 K_GetKartDriftSparkValue(player_t *player);
|
|||
INT32 K_StairJankFlip(INT32 value);
|
||||
INT32 K_GetKartDriftSparkValueForStage(player_t *player, UINT8 stage);
|
||||
void K_SpawnDriftBoostExplosion(player_t *player, int stage);
|
||||
void K_SpawnDriftElectricSparks(player_t *player);
|
||||
void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave);
|
||||
void K_KartUpdatePosition(player_t *player);
|
||||
mobj_t *K_CreatePaperItem(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 type, UINT8 amount);
|
||||
void K_DropItems(player_t *player);
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ extern struct menutransition_s {
|
|||
extern boolean menuwipe;
|
||||
|
||||
extern consvar_t cv_showfocuslost;
|
||||
extern consvar_t cv_chooseskin, cv_serversort;
|
||||
extern consvar_t cv_chooseskin, cv_serversort, cv_menujam_update;
|
||||
|
||||
void M_SetMenuDelay(UINT8 i);
|
||||
|
||||
|
|
|
|||
|
|
@ -3366,34 +3366,14 @@ void M_DrawItemToggles(void)
|
|||
cv = KartItemCVars[currentMenu->menuitems[thisitem].mvar1-1];
|
||||
translucent = (cv->value ? 0 : V_TRANSLUCENT);
|
||||
|
||||
switch (currentMenu->menuitems[thisitem].mvar1)
|
||||
{
|
||||
case KRITEM_DUALSNEAKER:
|
||||
case KRITEM_DUALJAWZ:
|
||||
drawnum = 2;
|
||||
break;
|
||||
case KRITEM_TRIPLESNEAKER:
|
||||
case KRITEM_TRIPLEBANANA:
|
||||
case KRITEM_TRIPLEORBINAUT:
|
||||
drawnum = 3;
|
||||
break;
|
||||
case KRITEM_QUADORBINAUT:
|
||||
drawnum = 4;
|
||||
break;
|
||||
case KRITEM_TENFOLDBANANA:
|
||||
drawnum = 10;
|
||||
break;
|
||||
default:
|
||||
drawnum = 0;
|
||||
break;
|
||||
}
|
||||
drawnum = K_ItemResultToAmount(currentMenu->menuitems[thisitem].mvar1);
|
||||
|
||||
if (cv->value)
|
||||
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ISBG", PU_CACHE));
|
||||
else
|
||||
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ISBGD", PU_CACHE));
|
||||
|
||||
if (drawnum != 0)
|
||||
if (drawnum > 1)
|
||||
{
|
||||
V_DrawScaledPatch(x, y, 0, W_CachePatchName("K_ISMUL", PU_CACHE));
|
||||
V_DrawScaledPatch(x, y, translucent, W_CachePatchName(K_GetItemPatch(currentMenu->menuitems[thisitem].mvar1, true), PU_CACHE));
|
||||
|
|
@ -3433,30 +3413,14 @@ void M_DrawItemToggles(void)
|
|||
cv = KartItemCVars[currentMenu->menuitems[itemOn].mvar1-1];
|
||||
translucent = (cv->value ? 0 : V_TRANSLUCENT);
|
||||
|
||||
switch (currentMenu->menuitems[itemOn].mvar1)
|
||||
{
|
||||
case KRITEM_DUALSNEAKER:
|
||||
case KRITEM_DUALJAWZ:
|
||||
drawnum = 2;
|
||||
break;
|
||||
case KRITEM_TRIPLESNEAKER:
|
||||
case KRITEM_TRIPLEBANANA:
|
||||
drawnum = 3;
|
||||
break;
|
||||
case KRITEM_TENFOLDBANANA:
|
||||
drawnum = 10;
|
||||
break;
|
||||
default:
|
||||
drawnum = 0;
|
||||
break;
|
||||
}
|
||||
drawnum = K_ItemResultToAmount(currentMenu->menuitems[itemOn].mvar1);
|
||||
|
||||
if (cv->value)
|
||||
V_DrawScaledPatch(onx-1, ony-2, 0, W_CachePatchName("K_ITBG", PU_CACHE));
|
||||
else
|
||||
V_DrawScaledPatch(onx-1, ony-2, 0, W_CachePatchName("K_ITBGD", PU_CACHE));
|
||||
|
||||
if (drawnum != 0)
|
||||
if (drawnum > 1)
|
||||
{
|
||||
V_DrawScaledPatch(onx-1, ony-2, 0, W_CachePatchName("K_ITMUL", PU_CACHE));
|
||||
V_DrawScaledPatch(onx-1, ony-2, translucent, W_CachePatchName(K_GetItemPatch(currentMenu->menuitems[itemOn].mvar1, false), PU_CACHE));
|
||||
|
|
|
|||
|
|
@ -143,6 +143,10 @@ consvar_t cv_showfocuslost = CVAR_INIT ("showfocuslost", "Yes", CV_SAVE, CV_YesN
|
|||
static CV_PossibleValue_t skins_cons_t[MAXSKINS+1] = {{1, DEFAULTSKIN}};
|
||||
consvar_t cv_chooseskin = CVAR_INIT ("chooseskin", DEFAULTSKIN, CV_HIDDEN, skins_cons_t, NULL);
|
||||
|
||||
consvar_t cv_menujam_update = CVAR_INIT ("menujam_update", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
static CV_PossibleValue_t menujam_cons_t[] = {{0, "menu"}, {1, "menu2"}, {2, "menu3"}, {0, NULL}};
|
||||
static consvar_t cv_menujam = CVAR_INIT ("menujam", "0", CV_SAVE, menujam_cons_t, NULL);
|
||||
|
||||
// This gametype list is integral for many different reasons.
|
||||
// When you add gametypes here, don't forget to update them in dehacked.c and doomstat.h!
|
||||
CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1];
|
||||
|
|
@ -945,7 +949,13 @@ void M_StartControlPanel(void)
|
|||
paused = false;
|
||||
CON_ToggleOff();
|
||||
|
||||
S_ChangeMusicInternal("menu", true);
|
||||
if (cv_menujam_update.value)
|
||||
{
|
||||
CV_AddValue(&cv_menujam, 1);
|
||||
CV_SetValue(&cv_menujam_update, 0);
|
||||
}
|
||||
|
||||
S_ChangeMusicInternal(cv_menujam.string, true);
|
||||
}
|
||||
|
||||
menuactive = true;
|
||||
|
|
@ -1686,6 +1696,14 @@ void M_Init(void)
|
|||
CV_RegisterVar(&cv_chooseskin);
|
||||
CV_RegisterVar(&cv_autorecord);
|
||||
|
||||
// don't lose your position in the jam cycle
|
||||
CV_RegisterVar(&cv_menujam_update);
|
||||
CV_RegisterVar(&cv_menujam);
|
||||
|
||||
#ifndef NONET
|
||||
CV_RegisterVar(&cv_serversort);
|
||||
#endif
|
||||
|
||||
if (dedicated)
|
||||
return;
|
||||
|
||||
|
|
@ -1712,20 +1730,6 @@ void M_Init(void)
|
|||
CV_RegisterVar(&cv_dummyaddonsearch);
|
||||
|
||||
M_UpdateMenuBGImage(true);
|
||||
|
||||
#if 0
|
||||
#ifdef HWRENDER
|
||||
// Permanently hide some options based on render mode
|
||||
if (rendermode == render_soft)
|
||||
OP_VideoOptionsMenu[op_video_ogl].status =
|
||||
OP_VideoOptionsMenu[op_video_kartman].status =
|
||||
OP_VideoOptionsMenu[op_video_md2] .status = IT_DISABLED;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
CV_RegisterVar(&cv_serversort);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ==================================================
|
||||
|
|
|
|||
|
|
@ -20,4 +20,13 @@ void Obj_SpawnItemDebrisEffects(mobj_t *collectible, mobj_t *collector);
|
|||
void Obj_ItemDebrisThink(mobj_t *debris);
|
||||
fixed_t Obj_ItemDebrisBounce(mobj_t *debris, fixed_t momz);
|
||||
|
||||
/* SPB */
|
||||
void Obj_SPBThink(mobj_t *spb);
|
||||
void Obj_SPBExplode(mobj_t *spb);
|
||||
void Obj_SPBTouch(mobj_t *spb, mobj_t *toucher);
|
||||
|
||||
/* SPB Juicebox Rings */
|
||||
void Obj_MantaRingThink(mobj_t *manta);
|
||||
mobj_t *Obj_MantaRingCreate(mobj_t *spb, mobj_t *owner, mobj_t *chase);
|
||||
|
||||
#endif/*k_objects_H*/
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ void K_DoIngameRespawn(player_t *player)
|
|||
|
||||
player->ringboost = 0;
|
||||
player->driftboost = player->strongdriftboost = 0;
|
||||
player->gateBoost = 0;
|
||||
|
||||
K_TumbleInterrupt(player);
|
||||
P_ResetPlayer(player);
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ static int player_get(lua_State *L)
|
|||
LUA_PushUserdata(L, plr->mo, META_MOBJ);
|
||||
else if (fastcmp(field,"cmd"))
|
||||
LUA_PushUserdata(L, &plr->cmd, META_TICCMD);
|
||||
else if (fastcmp(field,"oldcmd"))
|
||||
LUA_PushUserdata(L, &plr->oldcmd, META_TICCMD);
|
||||
else if (fastcmp(field,"respawn"))
|
||||
LUA_PushUserdata(L, &plr->respawn, META_RESPAWN);
|
||||
else if (fastcmp(field,"playerstate"))
|
||||
|
|
@ -250,6 +252,10 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->driftboost);
|
||||
else if (fastcmp(field,"strongdriftboost"))
|
||||
lua_pushinteger(L, plr->strongdriftboost);
|
||||
else if (fastcmp(field,"gateBoost"))
|
||||
lua_pushinteger(L, plr->gateBoost);
|
||||
else if (fastcmp(field,"gateSound"))
|
||||
lua_pushinteger(L, plr->gateSound);
|
||||
else if (fastcmp(field,"aizdriftstraft"))
|
||||
lua_pushinteger(L, plr->aizdriftstrat);
|
||||
else if (fastcmp(field,"aizdrifttilt"))
|
||||
|
|
@ -526,6 +532,8 @@ static int player_set(lua_State *L)
|
|||
}
|
||||
else if (fastcmp(field,"cmd"))
|
||||
return NOSET;
|
||||
else if (fastcmp(field,"oldcmd"))
|
||||
return NOSET;
|
||||
else if (fastcmp(field,"respawn"))
|
||||
return NOSET;
|
||||
else if (fastcmp(field,"playerstate"))
|
||||
|
|
@ -612,6 +620,12 @@ static int player_set(lua_State *L)
|
|||
plr->driftcharge = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"driftboost"))
|
||||
plr->driftboost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"strongdriftboost"))
|
||||
plr->strongdriftboost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"gateBoost"))
|
||||
plr->gateBoost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"gateSound"))
|
||||
plr->gateSound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"aizdriftstraft"))
|
||||
plr->aizdriftstrat = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"aizdrifttilt"))
|
||||
|
|
|
|||
|
|
@ -375,9 +375,6 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
} else if (fastcmp(word,"wantedcalcdelay")) {
|
||||
lua_pushinteger(L, wantedcalcdelay);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"indirectitemcooldown")) {
|
||||
lua_pushinteger(L, indirectitemcooldown);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"thwompsactive")) {
|
||||
lua_pushboolean(L, thwompsactive);
|
||||
return 1;
|
||||
|
|
@ -463,8 +460,6 @@ int LUA_WriteGlobals(lua_State *L, const char *word)
|
|||
racecountdown = (tic_t)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word,"exitcountdown"))
|
||||
exitcountdown = (tic_t)luaL_checkinteger(L, 2);
|
||||
else if (fastcmp(word,"indirectitemcooldown"))
|
||||
indirectitemcooldown = (tic_t)luaL_checkinteger(L, 2);
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1043,11 +1043,11 @@ void OP_ObjectplaceMovement(player_t *player)
|
|||
}
|
||||
|
||||
|
||||
if (player->pflags & PF_ATTACKDOWN)
|
||||
if (player->pflags & PF_STASIS)
|
||||
{
|
||||
// Are ANY objectplace buttons pressed? If no, remove flag.
|
||||
if (!(cmd->buttons & (BT_ATTACK|BT_DRIFT)))
|
||||
player->pflags &= ~PF_ATTACKDOWN;
|
||||
player->pflags &= ~PF_STASIS;
|
||||
|
||||
// Do nothing.
|
||||
return;
|
||||
|
|
@ -1056,12 +1056,12 @@ void OP_ObjectplaceMovement(player_t *player)
|
|||
/*if (cmd->buttons & BT_FORWARD)
|
||||
{
|
||||
OP_CycleThings(-1);
|
||||
player->pflags |= PF_ATTACKDOWN;
|
||||
player->pflags |= PF_STASIS;
|
||||
}
|
||||
else*/ if (cmd->buttons & BT_DRIFT)
|
||||
{
|
||||
OP_CycleThings(1);
|
||||
player->pflags |= PF_ATTACKDOWN;
|
||||
player->pflags |= PF_STASIS;
|
||||
}
|
||||
|
||||
// Place an object and add it to the maplist
|
||||
|
|
@ -1072,7 +1072,7 @@ void OP_ObjectplaceMovement(player_t *player)
|
|||
mobjtype_t spawnthing = op_currentdoomednum;
|
||||
boolean ceiling;
|
||||
|
||||
player->pflags |= PF_ATTACKDOWN;
|
||||
player->pflags |= PF_STASIS;
|
||||
|
||||
if (cv_mapthingnum.value > 0 && cv_mapthingnum.value < 4096)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
hyudoro.c
|
||||
shrink.c
|
||||
item-debris.c
|
||||
spb.c
|
||||
manta-ring.c
|
||||
|
|
|
|||
307
src/objects/manta-ring.c
Normal file
307
src/objects/manta-ring.c
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file manta-ring.c
|
||||
/// \brief SPB Juicebox rings. See spb.c for their spawning.
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
#include "../info.h"
|
||||
#include "../k_kart.h"
|
||||
#include "../k_objects.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "../r_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../g_game.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../k_waypoint.h"
|
||||
#include "../k_respawn.h"
|
||||
|
||||
#define MANTA_RACETIME (90)
|
||||
#define MANTA_MINTIME (15)
|
||||
#define MANTA_SPRINTTIME (60)
|
||||
|
||||
#define MANTA_ALIVEGATE (0)
|
||||
#define MANTA_DEADGATE (FF_TRANS80)
|
||||
|
||||
#define MANTA_SIZE (2 * FRACUNIT)
|
||||
#define MANTA_SIZEUP (10)
|
||||
#define MANTA_SIZESTRENGTH (1500)
|
||||
#define MANTA_MAXRAMP (80)
|
||||
|
||||
#define MANTA_COLLIDE (80 * FRACUNIT)
|
||||
|
||||
#define MANTA_TURBO (40)
|
||||
#define MANTA_FASTRAMP (17)
|
||||
#define MANTA_MINPWR (10)
|
||||
|
||||
#define manta_delay(o) ((o)->fuse)
|
||||
#define manta_timealive(o) ((o)->movecount)
|
||||
#define manta_boostval(o) ((o)->extravalue1)
|
||||
#define manta_laps(o) ((o)->extravalue2)
|
||||
#define manta_touched(o) ((o)->cusval)
|
||||
|
||||
#define manta_owner(o) ((o)->target)
|
||||
#define manta_chase(o) ((o)->tracer)
|
||||
|
||||
static boolean MantaAlreadyTouched(mobj_t *manta, player_t *player)
|
||||
{
|
||||
INT32 touchFlag = 0;
|
||||
|
||||
if (manta_chase(manta) != NULL && P_MobjWasRemoved(manta_chase(manta)) == false
|
||||
&& player->mo == manta_chase(manta))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (manta_laps(manta) < player->laps)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
touchFlag = 1 << (player - players);
|
||||
return (manta_touched(manta) & touchFlag);
|
||||
}
|
||||
|
||||
static void Obj_MantaCollide(mobj_t *manta, mobj_t *other)
|
||||
{
|
||||
// Could hook this into actual mobj collide if desired.
|
||||
fixed_t distance = INT32_MAX;
|
||||
fixed_t size = INT32_MAX;
|
||||
|
||||
INT32 addBoost = 0;
|
||||
INT32 touchFlag = 0;
|
||||
|
||||
size_t i;
|
||||
|
||||
distance = P_AproxDistance(P_AproxDistance(
|
||||
other->x - manta->x,
|
||||
other->y - manta->y),
|
||||
other->z - manta->z) - other->radius - manta->radius;
|
||||
|
||||
size = FixedMul(MANTA_COLLIDE, mapobjectscale);
|
||||
|
||||
if (distance > size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (other->player != NULL) // Just in case other objects should be added?
|
||||
{
|
||||
if (MantaAlreadyTouched(manta, other->player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
touchFlag = 1 << (other->player - players);
|
||||
}
|
||||
|
||||
addBoost = manta_boostval(manta);
|
||||
|
||||
if (manta_timealive(manta) < MANTA_FASTRAMP)
|
||||
{
|
||||
// Ramp up to max power.
|
||||
addBoost = FixedMul(addBoost * FRACUNIT, (manta_timealive(manta) * FRACUNIT) / MANTA_FASTRAMP);
|
||||
|
||||
// Convert to integer
|
||||
addBoost = (addBoost + (FRACUNIT/2)) / FRACUNIT;
|
||||
|
||||
// Cap it
|
||||
addBoost = max(MANTA_MINPWR, addBoost);
|
||||
}
|
||||
|
||||
if (other->player != NULL)
|
||||
{
|
||||
UINT8 snd = 0;
|
||||
|
||||
if (other->player->speedboost > FRACUNIT/4)
|
||||
{
|
||||
snd = other->player->gateSound;
|
||||
other->player->gateSound++;
|
||||
|
||||
if (other->player->gateSound > 4)
|
||||
{
|
||||
other->player->gateSound = 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
other->player->gateSound = 0;
|
||||
}
|
||||
|
||||
K_SpawnDriftBoostExplosion(other->player, 3);
|
||||
K_SpawnDriftElectricSparks(other->player, SKINCOLOR_CRIMSON, true);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
S_StopSoundByID(other, sfx_gate01 + i);
|
||||
}
|
||||
|
||||
S_StartSound(other, sfx_gate01 + snd);
|
||||
other->player->gateBoost += addBoost/2;
|
||||
|
||||
if (P_IsDisplayPlayer(other->player) == true)
|
||||
{
|
||||
P_StartQuake(12 << FRACBITS, 6);
|
||||
}
|
||||
}
|
||||
|
||||
if (touchFlag > 0)
|
||||
{
|
||||
manta_touched(manta) |= touchFlag;
|
||||
}
|
||||
}
|
||||
|
||||
static void RunMantaCollide(mobj_t *manta)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *player = NULL;
|
||||
|
||||
if (playeringame[i] == false)
|
||||
{
|
||||
// Invalid
|
||||
continue;
|
||||
}
|
||||
|
||||
player = &players[i];
|
||||
if (player->spectator == true)
|
||||
{
|
||||
// Not playing.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
|
||||
{
|
||||
// Invalid object
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->mo == manta_chase(manta))
|
||||
{
|
||||
// Don't allow the person being chased to touch this.
|
||||
continue;
|
||||
}
|
||||
|
||||
Obj_MantaCollide(manta, player->mo);
|
||||
}
|
||||
}
|
||||
|
||||
static void RunMantaVisual(mobj_t *manta)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
if (manta->fuse < 5*TICRATE)
|
||||
{
|
||||
if (leveltime & 1)
|
||||
{
|
||||
manta->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
else
|
||||
{
|
||||
manta->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
const UINT8 pID = displayplayers[i];
|
||||
player_t *player = &players[pID];
|
||||
|
||||
if (MantaAlreadyTouched(manta, player) == false)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > r_splitscreen)
|
||||
{
|
||||
manta->frame = (manta->frame & ~FF_TRANSMASK) | MANTA_DEADGATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
manta->frame = (manta->frame & ~FF_TRANSMASK) | MANTA_ALIVEGATE;
|
||||
}
|
||||
}
|
||||
|
||||
void Obj_MantaRingThink(mobj_t *manta)
|
||||
{
|
||||
RunMantaVisual(manta);
|
||||
|
||||
if (manta_delay(manta) % MANTA_SIZEUP == 0)
|
||||
{
|
||||
manta->destscale += FixedMul(MANTA_SIZESTRENGTH, mapobjectscale);
|
||||
manta_boostval(manta) = min(MANTA_MAXRAMP, manta_boostval(manta) + 1);
|
||||
}
|
||||
|
||||
manta_timealive(manta)++;
|
||||
|
||||
RunMantaCollide(manta);
|
||||
}
|
||||
|
||||
mobj_t *Obj_MantaRingCreate(mobj_t *spb, mobj_t *owner, mobj_t *chase)
|
||||
{
|
||||
mobj_t *manta = NULL;
|
||||
INT32 delay = 0;
|
||||
|
||||
manta = P_SpawnMobjFromMobj(spb, 0, 0, 0, MT_MANTARING);
|
||||
|
||||
manta->color = SKINCOLOR_KETCHUP;
|
||||
|
||||
manta->destscale = FixedMul(MANTA_SIZE, spb->scale);
|
||||
P_SetScale(manta, manta->destscale);
|
||||
|
||||
manta->angle = R_PointToAngle2(0, 0, spb->momx, spb->momy) + ANGLE_90;
|
||||
|
||||
// Set boost value
|
||||
manta_boostval(manta) = MANTA_TURBO;
|
||||
|
||||
// Set despawn delay
|
||||
delay = max(MANTA_MINTIME, MANTA_RACETIME / mapheaderinfo[gamemap - 1]->numlaps);
|
||||
|
||||
if (mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
||||
{
|
||||
delay = MANTA_SPRINTTIME;
|
||||
}
|
||||
|
||||
manta_delay(manta) = delay * TICRATE;
|
||||
|
||||
// Default if neither object exists
|
||||
manta_laps(manta) = INT32_MAX;
|
||||
|
||||
// Set owner
|
||||
if (owner != NULL && P_MobjWasRemoved(owner) == false)
|
||||
{
|
||||
P_SetTarget(&manta_owner(manta), owner);
|
||||
|
||||
if (owner->player != NULL)
|
||||
{
|
||||
// Default if chaser doesn't exist
|
||||
manta_laps(manta) = owner->player->laps;
|
||||
}
|
||||
}
|
||||
|
||||
// Set chaser
|
||||
if (chase != NULL && P_MobjWasRemoved(chase) == false)
|
||||
{
|
||||
P_SetTarget(&manta_chase(manta), chase);
|
||||
|
||||
if (chase->player != NULL)
|
||||
{
|
||||
manta_laps(manta) = chase->player->laps;
|
||||
}
|
||||
}
|
||||
|
||||
return manta;
|
||||
}
|
||||
|
|
@ -439,6 +439,8 @@ void Obj_PohbeeThinker(mobj_t *pohbee)
|
|||
{
|
||||
mobj_t *gun = NULL;
|
||||
|
||||
K_SetItemCooldown(KITEM_SHRINK, 20*TICRATE);
|
||||
|
||||
pohbee->momx = pohbee->momy = pohbee->momz = 0;
|
||||
pohbee->spritexscale = pohbee->spriteyscale = 2*FRACUNIT;
|
||||
|
||||
|
|
@ -482,6 +484,8 @@ void Obj_PohbeeRemoved(mobj_t *pohbee)
|
|||
P_RemoveMobj(gun);
|
||||
gun = nextGun;
|
||||
}
|
||||
|
||||
P_SetTarget(&pohbee_guns(pohbee), NULL);
|
||||
}
|
||||
|
||||
void Obj_ShrinkGunRemoved(mobj_t *gun)
|
||||
|
|
@ -493,6 +497,8 @@ void Obj_ShrinkGunRemoved(mobj_t *gun)
|
|||
P_RemoveMobj(gun_laser(gun));
|
||||
}
|
||||
|
||||
P_SetTarget(&gun_laser(gun), NULL);
|
||||
|
||||
chain = gun_chains(gun);
|
||||
while (chain != NULL && P_MobjWasRemoved(chain) == false)
|
||||
{
|
||||
|
|
@ -500,6 +506,8 @@ void Obj_ShrinkGunRemoved(mobj_t *gun)
|
|||
P_RemoveMobj(chain);
|
||||
chain = nextChain;
|
||||
}
|
||||
|
||||
P_SetTarget(&gun_chains(gun), NULL);
|
||||
}
|
||||
|
||||
boolean Obj_ShrinkLaserCollide(mobj_t *gun, mobj_t *victim)
|
||||
|
|
|
|||
1024
src/objects/spb.c
Normal file
1024
src/objects/spb.c
Normal file
File diff suppressed because it is too large
Load diff
549
src/p_enemy.c
549
src/p_enemy.c
|
|
@ -312,7 +312,6 @@ void A_ChangeHeight(mobj_t *actor);
|
|||
void A_ItemPop(mobj_t *actor);
|
||||
void A_JawzChase(mobj_t *actor);
|
||||
void A_JawzExplode(mobj_t *actor);
|
||||
void A_SPBChase(mobj_t *actor);
|
||||
void A_SSMineSearch(mobj_t *actor);
|
||||
void A_SSMineExplode(mobj_t *actor);
|
||||
void A_LandMineExplode(mobj_t *actor);
|
||||
|
|
@ -13210,7 +13209,6 @@ void A_ItemPop(mobj_t *actor)
|
|||
|
||||
void A_JawzChase(mobj_t *actor)
|
||||
{
|
||||
const fixed_t currentspeed = R_PointToDist2(0, 0, actor->momx, actor->momy);
|
||||
player_t *player;
|
||||
fixed_t thrustamount = 0;
|
||||
fixed_t frictionsafety = (actor->friction == 0) ? 1 : actor->friction;
|
||||
|
|
@ -13295,30 +13293,29 @@ void A_JawzChase(mobj_t *actor)
|
|||
P_SetTarget(&actor->tracer, NULL);
|
||||
}
|
||||
|
||||
if (!P_IsObjectOnGround(actor))
|
||||
{
|
||||
// No friction in the air
|
||||
frictionsafety = FRACUNIT;
|
||||
}
|
||||
|
||||
if (currentspeed >= topspeed)
|
||||
{
|
||||
// Thrust as if you were at top speed, slow down naturally
|
||||
thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
|
||||
// Thrust to immediately get to top speed
|
||||
thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety);
|
||||
}
|
||||
|
||||
if (!actor->tracer)
|
||||
{
|
||||
actor->angle = K_MomentumAngle(actor);
|
||||
}
|
||||
|
||||
P_Thrust(actor, actor->angle, thrustamount);
|
||||
if (P_IsObjectOnGround(actor))
|
||||
{
|
||||
const fixed_t currentspeed = R_PointToDist2(0, 0, actor->momx, actor->momy);
|
||||
|
||||
if (currentspeed >= topspeed)
|
||||
{
|
||||
// Thrust as if you were at top speed, slow down naturally
|
||||
thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
|
||||
// Thrust to immediately get to top speed
|
||||
thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety);
|
||||
}
|
||||
|
||||
P_Thrust(actor, actor->angle, thrustamount);
|
||||
}
|
||||
|
||||
if ((actor->tracer != NULL) && (actor->tracer->health > 0))
|
||||
return;
|
||||
|
|
@ -13372,516 +13369,6 @@ void A_JawzExplode(mobj_t *actor)
|
|||
return;
|
||||
}
|
||||
|
||||
static void SpawnSPBTrailRings(mobj_t *actor)
|
||||
{
|
||||
I_Assert(actor != NULL);
|
||||
|
||||
if (leveltime % 6 == 0)
|
||||
{
|
||||
if (leveltime % (actor->extravalue1 == 2 ? 6 : 3) == 0) // Extravalue1 == 2 is seeking mode. Because the SPB is about twice as fast as normal in that mode, also spawn the rings twice as often to make up for it!
|
||||
{
|
||||
mobj_t *ring = P_SpawnMobj(actor->x - actor->momx, actor->y - actor->momy,
|
||||
actor->z - actor->momz + (24*mapobjectscale), MT_RING);
|
||||
ring->threshold = 10;
|
||||
ring->fuse = 35*TICRATE;
|
||||
ring->colorized = true;
|
||||
ring->color = SKINCOLOR_RED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spawns the V shaped dust. To be used when the SPB is going mostly forward.
|
||||
static void SpawnSPBDust(mobj_t *mo)
|
||||
{
|
||||
// The easiest way to spawn a V shaped cone of dust from the SPB is simply to spawn 2 particles, and to both move them to the sides in opposite direction.
|
||||
mobj_t *dust;
|
||||
fixed_t sx;
|
||||
fixed_t sy;
|
||||
fixed_t sz = mo->floorz;
|
||||
angle_t sa = mo->angle - ANG1*60;
|
||||
INT32 i;
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
sz = mo->ceilingz;
|
||||
|
||||
if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*64) // Only ever other frame. Also don't spawn it if we're way above the ground.
|
||||
{
|
||||
// Determine spawning position next to the SPB:
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
sx = mo->x + FixedMul((mo->scale*96), FINECOSINE((sa)>>ANGLETOFINESHIFT));
|
||||
sy = mo->y + FixedMul((mo->scale*96), FINESINE((sa)>>ANGLETOFINESHIFT));
|
||||
|
||||
dust = P_SpawnMobj(sx, sy, sz, MT_SPBDUST);
|
||||
dust->momx = mo->momx/2;
|
||||
dust->momy = mo->momy/2;
|
||||
dust->momz = mo->momz/2; // Give some of the momentum to the dust
|
||||
P_SetScale(dust, mo->scale*2);
|
||||
dust->colorized = true;
|
||||
dust->color = SKINCOLOR_RED;
|
||||
P_InitAngle(dust, mo->angle - FixedAngle(FRACUNIT*90 - FRACUNIT*180*i)); // The first one will spawn to the right of the spb, the second one to the left.
|
||||
P_Thrust(dust, dust->angle, 6*dust->scale);
|
||||
|
||||
K_MatchGenericExtraFlags(dust, mo);
|
||||
|
||||
sa += ANG1*120; // Add 120 degrees to get to mo->angle + ANG1*60
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spawns SPB slip tide. To be used when the SPB is turning.
|
||||
// Modified version of K_SpawnAIZDust. Maybe we could merge those to be cleaner?
|
||||
|
||||
// dir should be either 1 or -1 to determine where to spawn the dust.
|
||||
|
||||
static void SpawnSPBAIZDust(mobj_t *mo, INT32 dir)
|
||||
{
|
||||
fixed_t newx;
|
||||
fixed_t newy;
|
||||
mobj_t *spark;
|
||||
angle_t travelangle;
|
||||
fixed_t sz = mo->floorz;
|
||||
|
||||
if (mo->eflags & MFE_VERTICALFLIP)
|
||||
sz = mo->ceilingz;
|
||||
|
||||
travelangle = K_MomentumAngle(mo);
|
||||
if (leveltime & 1 && abs(mo->z - sz) < FRACUNIT*64)
|
||||
{
|
||||
newx = mo->x + P_ReturnThrustX(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale));
|
||||
newy = mo->y + P_ReturnThrustY(mo, travelangle - (dir*ANGLE_45), FixedMul(24*FRACUNIT, mo->scale));
|
||||
spark = P_SpawnMobj(newx, newy, sz, MT_AIZDRIFTSTRAT);
|
||||
spark->colorized = true;
|
||||
spark->color = SKINCOLOR_RED;
|
||||
spark->flags = MF_NOGRAVITY|MF_PAIN;
|
||||
P_SetTarget(&spark->target, mo);
|
||||
|
||||
P_InitAngle(spark, travelangle+(dir*ANGLE_90));
|
||||
P_SetScale(spark, (spark->destscale = mo->scale*3/2));
|
||||
|
||||
spark->momx = (6*mo->momx)/5;
|
||||
spark->momy = (6*mo->momy)/5;
|
||||
|
||||
K_MatchGenericExtraFlags(spark, mo);
|
||||
}
|
||||
}
|
||||
|
||||
// Used for seeking and when SPB is trailing its target from way too close!
|
||||
static void SpawnSPBSpeedLines(mobj_t *actor)
|
||||
{
|
||||
mobj_t *fast = P_SpawnMobj(actor->x + (P_RandomRange(-24,24) * actor->scale),
|
||||
actor->y + (P_RandomRange(-24,24) * actor->scale),
|
||||
actor->z + (actor->height/2) + (P_RandomRange(-24,24) * actor->scale),
|
||||
MT_FASTLINE);
|
||||
|
||||
P_SetTarget(&fast->target, actor);
|
||||
P_InitAngle(fast, K_MomentumAngle(actor));
|
||||
fast->color = SKINCOLOR_RED;
|
||||
fast->colorized = true;
|
||||
K_MatchGenericExtraFlags(fast, actor);
|
||||
}
|
||||
|
||||
|
||||
void A_SPBChase(mobj_t *actor)
|
||||
{
|
||||
player_t *player = NULL;
|
||||
player_t *scplayer = NULL; // secondary target for seeking
|
||||
UINT8 i;
|
||||
UINT8 bestrank = UINT8_MAX;
|
||||
fixed_t dist;
|
||||
angle_t hang, vang;
|
||||
fixed_t wspeed, xyspeed, zspeed;
|
||||
fixed_t pdist = 1536<<FRACBITS; // best player distance when seeking
|
||||
angle_t pangle; // angle between us and the player
|
||||
|
||||
if (LUA_CallAction(A_SPBCHASE, actor))
|
||||
return;
|
||||
|
||||
// Default speed
|
||||
wspeed = FixedMul(mapobjectscale, K_GetKartSpeedFromStat(5)*2); // Go at twice the average speed a player would be going at!
|
||||
|
||||
if (actor->threshold) // Just fired, go straight.
|
||||
{
|
||||
actor->lastlook = -1;
|
||||
actor->cusval = -1;
|
||||
spbplace = -1;
|
||||
P_InstaThrust(actor, actor->angle, wspeed);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the player with the best rank
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].exiting)
|
||||
continue; // not in-game
|
||||
|
||||
/*if (!players[i].mo)
|
||||
continue; // no mobj
|
||||
|
||||
if (players[i].mo->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
if (players[i].respawn.state != RESPAWNST_NONE)
|
||||
continue;*/ // respawning
|
||||
|
||||
if (players[i].position < bestrank)
|
||||
{
|
||||
bestrank = players[i].position;
|
||||
player = &players[i];
|
||||
}
|
||||
}
|
||||
|
||||
// lastlook = last player num targetted
|
||||
// cvmem = stored speed
|
||||
// cusval = next waypoint heap index
|
||||
// extravalue1 = SPB movement mode
|
||||
// extravalue2 = mode misc option
|
||||
|
||||
if (actor->extravalue1 == 1) // MODE: TARGETING
|
||||
{
|
||||
actor->cusval = -1; // Reset waypoint
|
||||
|
||||
if (actor->tracer && actor->tracer->health)
|
||||
{
|
||||
fixed_t defspeed = wspeed;
|
||||
fixed_t range = (160*actor->tracer->scale);
|
||||
fixed_t cx = 0, cy =0;
|
||||
|
||||
// Play the intimidating gurgle
|
||||
if (!S_SoundPlaying(actor, actor->info->activesound))
|
||||
S_StartSound(actor, actor->info->activesound);
|
||||
|
||||
// Maybe we want SPB to target an object later? IDK lol
|
||||
if (actor->tracer->player)
|
||||
{
|
||||
UINT8 fracmax = 32;
|
||||
UINT8 spark = ((10-actor->tracer->player->kartspeed) + actor->tracer->player->kartweight) / 2;
|
||||
fixed_t easiness = ((actor->tracer->player->kartspeed + (10-spark)) << FRACBITS) / 2;
|
||||
|
||||
actor->lastlook = actor->tracer->player-players; // Save the player num for death scumming...
|
||||
actor->tracer->player->pflags |= PF_RINGLOCK; // set ring lock
|
||||
|
||||
if (actor->tracer->hitlag)
|
||||
{
|
||||
// If the player is frozen through no fault of their own, the SPB should be too.
|
||||
actor->hitlag = actor->tracer->hitlag;
|
||||
}
|
||||
|
||||
if (!P_IsObjectOnGround(actor->tracer))
|
||||
{
|
||||
// In the air you have no control; basically don't hit unless you make a near complete stop
|
||||
defspeed = (7 * actor->tracer->player->speed) / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 7/8ths max speed for Knuckles, 3/4ths max speed for min accel, exactly max speed for max accel
|
||||
defspeed = FixedMul(((fracmax+1)<<FRACBITS) - easiness, K_GetKartSpeed(actor->tracer->player, false, false)) / fracmax;
|
||||
}
|
||||
|
||||
// Be fairer on conveyors
|
||||
cx = actor->tracer->player->cmomx;
|
||||
cy = actor->tracer->player->cmomy;
|
||||
|
||||
// Switch targets if you're no longer 1st for long enough
|
||||
if (actor->tracer->player->position <= bestrank)
|
||||
actor->extravalue2 = 7*TICRATE;
|
||||
else if (actor->extravalue2-- <= 0)
|
||||
actor->extravalue1 = 0; // back to SEEKING
|
||||
|
||||
spbplace = actor->tracer->player->position;
|
||||
}
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
|
||||
|
||||
wspeed = FixedMul(defspeed, FRACUNIT + FixedDiv(dist-range, range));
|
||||
if (wspeed < defspeed)
|
||||
wspeed = defspeed;
|
||||
if (wspeed > (3*defspeed)/2)
|
||||
wspeed = (3*defspeed)/2;
|
||||
if (wspeed < 20*actor->tracer->scale)
|
||||
wspeed = 20*actor->tracer->scale;
|
||||
if (actor->tracer->player->carry == CR_SLIDING)
|
||||
wspeed = actor->tracer->player->speed/2;
|
||||
// ^^^^ current section: These are annoying, and grand metropolis in particular needs this.
|
||||
|
||||
hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
|
||||
vang = R_PointToAngle2(0, actor->z, dist, actor->tracer->z);
|
||||
|
||||
// Modify stored speed
|
||||
if (wspeed > actor->cvmem)
|
||||
actor->cvmem += (wspeed - actor->cvmem) / TICRATE;
|
||||
else
|
||||
actor->cvmem = wspeed;
|
||||
|
||||
{
|
||||
// Smoothly rotate horz angle
|
||||
angle_t input = hang - actor->angle;
|
||||
boolean invert = (input > ANGLE_180);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
// Slow down when turning; it looks better and makes U-turns not unfair
|
||||
xyspeed = FixedMul(actor->cvmem, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/4);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
actor->angle += input;
|
||||
|
||||
// Smoothly rotate vert angle
|
||||
input = vang - actor->movedir;
|
||||
invert = (input > ANGLE_180);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
// Slow down when turning; might as well do it for momz, since we do it above too
|
||||
zspeed = FixedMul(actor->cvmem, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/4);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
actor->movedir += input;
|
||||
}
|
||||
|
||||
actor->momx = cx + FixedMul(FixedMul(xyspeed, FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
actor->momy = cy + FixedMul(FixedMul(xyspeed, FINESINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
|
||||
// Spawn a trail of rings behind the SPB!
|
||||
SpawnSPBTrailRings(actor);
|
||||
|
||||
// Red speed lines for when it's gaining on its target. A tell for when you're starting to lose too much speed!
|
||||
if (R_PointToDist2(0, 0, actor->momx, actor->momy) > (actor->tracer->player ? (16*actor->tracer->player->speed)/15
|
||||
: (16*R_PointToDist2(0, 0, actor->tracer->momx, actor->tracer->momy))/15) // Going faster than the target
|
||||
&& xyspeed > K_GetKartSpeed(actor->tracer->player, false, false) / 4) // Don't display speedup lines at pitifully low speeds
|
||||
SpawnSPBSpeedLines(actor);
|
||||
|
||||
return;
|
||||
}
|
||||
else // Target's gone, return to SEEKING
|
||||
{
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
actor->extravalue1 = 2; // WAIT...
|
||||
actor->extravalue2 = 52; // Slightly over the respawn timer length
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (actor->extravalue1 == 2) // MODE: WAIT...
|
||||
{
|
||||
actor->momx = actor->momy = actor->momz = 0; // Stoooop
|
||||
actor->cusval = -1; // Reset waypoint
|
||||
|
||||
if (actor->lastlook != -1
|
||||
&& playeringame[actor->lastlook]
|
||||
&& !players[actor->lastlook].spectator
|
||||
&& !players[actor->lastlook].exiting)
|
||||
{
|
||||
spbplace = players[actor->lastlook].position;
|
||||
players[actor->lastlook].pflags |= PF_RINGLOCK;
|
||||
if (actor->extravalue2-- <= 0 && players[actor->lastlook].mo)
|
||||
{
|
||||
P_SetTarget(&actor->tracer, players[actor->lastlook].mo);
|
||||
actor->extravalue1 = 1; // TARGET ACQUIRED
|
||||
actor->extravalue2 = 7*TICRATE;
|
||||
actor->cvmem = wspeed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->extravalue1 = 0; // SEEKING
|
||||
actor->extravalue2 = 0;
|
||||
spbplace = -1;
|
||||
}
|
||||
}
|
||||
else // MODE: SEEKING
|
||||
{
|
||||
waypoint_t *lastwaypoint = NULL;
|
||||
waypoint_t *bestwaypoint = NULL;
|
||||
waypoint_t *nextwaypoint = NULL;
|
||||
waypoint_t *tempwaypoint = NULL;
|
||||
|
||||
actor->lastlook = -1; // Just make sure this is reset
|
||||
|
||||
if (!player || !player->mo || player->mo->health <= 0 || (player->respawn.state != RESPAWNST_NONE))
|
||||
{
|
||||
// No one there? Completely STOP.
|
||||
actor->momx = actor->momy = actor->momz = 0;
|
||||
if (!player)
|
||||
spbplace = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Found someone, now get close enough to initiate the slaughter...
|
||||
P_SetTarget(&actor->tracer, player->mo);
|
||||
spbplace = bestrank;
|
||||
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
|
||||
|
||||
/*
|
||||
K_GetBestWaypointForMobj returns the waypoint closest to the object that isn't its current waypoint. While this is usually good enough,
|
||||
in cases where the track overlaps, this means that the SPB will sometimes target a waypoint on an earlier/later portion of the track instead of following along.
|
||||
For this reason, we're going to try and make sure to avoid these situations.
|
||||
*/
|
||||
|
||||
// Move along the waypoints until you get close enough
|
||||
if (actor->cusval > -1 && actor->extravalue2 > 0)
|
||||
{
|
||||
// Previously set nextwaypoint
|
||||
lastwaypoint = K_GetWaypointFromIndex((size_t)actor->cusval);
|
||||
tempwaypoint = K_GetBestWaypointForMobj(actor);
|
||||
// check if the tempwaypoint corresponds to lastwaypoint's next ID at least;
|
||||
// This is to avoid situations where the SPB decides to suicide jump down a bridge because it found a COMPLETELY unrelated waypoint down there.
|
||||
|
||||
if (K_GetWaypointID(tempwaypoint) == K_GetWaypointNextID(lastwaypoint) || K_GetWaypointID(tempwaypoint) == K_GetWaypointID(lastwaypoint))
|
||||
// either our previous or curr waypoint ID, sure, take it
|
||||
bestwaypoint = tempwaypoint;
|
||||
else
|
||||
bestwaypoint = K_GetWaypointFromIndex((size_t)actor->extravalue2); // keep going from the PREVIOUS wp.
|
||||
}
|
||||
else
|
||||
bestwaypoint = K_GetBestWaypointForMobj(actor);
|
||||
|
||||
if (bestwaypoint == NULL && lastwaypoint == NULL)
|
||||
{
|
||||
// We have invalid waypoints all around, so use closest to try and make it non-NULL.
|
||||
bestwaypoint = K_GetClosestWaypointToMobj(actor);
|
||||
}
|
||||
|
||||
if (bestwaypoint != NULL)
|
||||
{
|
||||
const boolean huntbackwards = false;
|
||||
boolean useshortcuts = false;
|
||||
|
||||
// If the player is on a shortcut, use shortcuts. No escape.
|
||||
if (K_GetWaypointIsShortcut(player->nextwaypoint))
|
||||
{
|
||||
useshortcuts = true;
|
||||
}
|
||||
|
||||
nextwaypoint = K_GetNextWaypointToDestination(
|
||||
bestwaypoint, player->nextwaypoint, useshortcuts, huntbackwards);
|
||||
}
|
||||
|
||||
if (nextwaypoint == NULL && lastwaypoint != NULL)
|
||||
{
|
||||
// Restore to the last nextwaypoint
|
||||
nextwaypoint = lastwaypoint;
|
||||
}
|
||||
|
||||
if (nextwaypoint != NULL)
|
||||
{
|
||||
const fixed_t xywaypointdist = P_AproxDistance(
|
||||
actor->x - nextwaypoint->mobj->x, actor->y - nextwaypoint->mobj->y);
|
||||
|
||||
hang = R_PointToAngle2(actor->x, actor->y, nextwaypoint->mobj->x, nextwaypoint->mobj->y);
|
||||
vang = R_PointToAngle2(0, actor->z, xywaypointdist, nextwaypoint->mobj->z);
|
||||
|
||||
actor->cusval = (INT32)K_GetWaypointHeapIndex(nextwaypoint);
|
||||
actor->extravalue2 = (INT32)K_GetWaypointHeapIndex(bestwaypoint); // save our last best, used above.
|
||||
}
|
||||
else
|
||||
{
|
||||
// continue straight ahead... Shouldn't happen.
|
||||
hang = actor->angle;
|
||||
vang = 0U;
|
||||
}
|
||||
|
||||
{
|
||||
// Smoothly rotate horz angle
|
||||
angle_t input = hang - actor->angle;
|
||||
boolean invert = (input > ANGLE_180);
|
||||
INT32 turnangle;
|
||||
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/8);
|
||||
|
||||
// Slow down when turning; it looks better and makes U-turns not unfair
|
||||
xyspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
actor->angle += input;
|
||||
|
||||
// If input is small enough, spawn dust. Otherwise, spawn a slip tide!
|
||||
turnangle = AngleFixed(input)/FRACUNIT;
|
||||
|
||||
// The SPB is really turning if that value is >= 3 and <= 357. This looks pretty bad check-wise so feel free to change it for something that isn't as terrible.
|
||||
if (turnangle >= 3 && turnangle <= 357)
|
||||
SpawnSPBAIZDust(actor, turnangle < 180 ? 1 : -1); // 1 if turning left, -1 if turning right. Angles work counterclockwise, remember!
|
||||
else
|
||||
SpawnSPBDust(actor); // if we're mostly going straight, then spawn the V dust cone!
|
||||
|
||||
SpawnSPBSpeedLines(actor); // Always spawn speed lines while seeking
|
||||
|
||||
// Smoothly rotate vert angle
|
||||
input = vang - actor->movedir;
|
||||
invert = (input > ANGLE_180);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/8);
|
||||
|
||||
// Slow down when turning; might as well do it for momz, since we do it above too
|
||||
zspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
actor->movedir += input;
|
||||
}
|
||||
|
||||
actor->momx = FixedMul(FixedMul(xyspeed, FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
actor->momy = FixedMul(FixedMul(xyspeed, FINESINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT));
|
||||
|
||||
// see if a player is near us, if they are, try to hit them by slightly thrusting towards them, otherwise, bleh!
|
||||
for (i=0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].exiting)
|
||||
continue; // not in-game
|
||||
|
||||
if (R_PointToDist2(actor->x, actor->y, players[i].mo->x, players[i].mo->y) < pdist)
|
||||
{
|
||||
pdist = R_PointToDist2(actor->x, actor->y, players[i].mo->x, players[i].mo->y);
|
||||
scplayer = &players[i]; // it doesn't matter if we override this guy now.
|
||||
}
|
||||
}
|
||||
|
||||
// different player from our main target, try and ram into em~!
|
||||
if (scplayer && scplayer != player)
|
||||
{
|
||||
pangle = actor->angle - R_PointToAngle2(actor->x, actor->y,scplayer->mo->x, scplayer->mo->y);
|
||||
// check if the angle wouldn't make us LOSE speed...
|
||||
if ((INT32)pangle/ANG1 >= -80 && (INT32)pangle/ANG1 <= 80) // allow for around 80 degrees
|
||||
{
|
||||
// Thrust us towards the guy, try to screw em up!
|
||||
P_Thrust(actor, R_PointToAngle2(actor->x, actor->y, scplayer->mo->x, scplayer->mo->y), actor->movefactor/4); // not too fast though.
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn a trail of rings behind the SPB!
|
||||
SpawnSPBTrailRings(actor);
|
||||
|
||||
if (dist <= (1024*actor->tracer->scale) && !(actor->flags2 & MF2_AMBUSH)) // Close enough to target? Use Ambush flag to disable targetting so I can have an easier time testing stuff...
|
||||
{
|
||||
S_StartSound(actor, actor->info->attacksound);
|
||||
actor->extravalue1 = 1; // TARGET ACQUIRED
|
||||
actor->extravalue2 = 7*TICRATE;
|
||||
actor->cvmem = wspeed;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, no matter what, the spb should not be able to be under the ground, or above the ceiling;
|
||||
if (actor->z < actor->floorz)
|
||||
actor->z = actor->floorz;
|
||||
else if (actor->z > actor->ceilingz - actor->height)
|
||||
actor->z = actor->ceilingz - actor->height;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void A_SSMineSearch(mobj_t *actor)
|
||||
{
|
||||
fixed_t dis = INT32_MAX;
|
||||
|
|
|
|||
|
|
@ -352,41 +352,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
}
|
||||
return;
|
||||
case MT_SPB:
|
||||
if ((special->target == toucher || special->target == toucher->target) && (special->threshold > 0))
|
||||
return;
|
||||
|
||||
if (special->health <= 0 || toucher->health <= 0)
|
||||
return;
|
||||
|
||||
if (player->spectator)
|
||||
return;
|
||||
|
||||
if (special->tracer && !P_MobjWasRemoved(special->tracer) && toucher == special->tracer)
|
||||
{
|
||||
mobj_t *spbexplode;
|
||||
|
||||
if (player->bubbleblowup > 0)
|
||||
{
|
||||
K_DropHnextList(player, false);
|
||||
special->extravalue1 = 2; // WAIT...
|
||||
special->extravalue2 = 52; // Slightly over the respawn timer length
|
||||
return;
|
||||
}
|
||||
|
||||
S_StopSound(special); // Don't continue playing the gurgle or the siren
|
||||
|
||||
spbexplode = P_SpawnMobj(toucher->x, toucher->y, toucher->z, MT_SPBEXPLOSION);
|
||||
spbexplode->extravalue1 = 1; // Tell K_ExplodePlayer to use extra knockback
|
||||
if (special->target && !P_MobjWasRemoved(special->target))
|
||||
P_SetTarget(&spbexplode->target, special->target);
|
||||
|
||||
P_RemoveMobj(special);
|
||||
Obj_SPBTouch(special, toucher);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
P_DamageMobj(player->mo, special, special->target, 1, DMG_NORMAL);
|
||||
}
|
||||
return;
|
||||
case MT_EMERALD:
|
||||
if (!P_CanPickupItem(player, 0))
|
||||
return;
|
||||
|
|
@ -2060,9 +2029,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
player->sneakertimer = player->numsneakers = 0;
|
||||
player->driftboost = player->strongdriftboost = 0;
|
||||
player->gateBoost = 0;
|
||||
player->ringboost = 0;
|
||||
player->glanceDir = 0;
|
||||
player->pflags &= ~PF_LOOKDOWN;
|
||||
player->pflags &= ~PF_GAINAX;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
|
|
|||
138
src/p_mobj.c
138
src/p_mobj.c
|
|
@ -1594,21 +1594,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
else if (P_MobjWasRemoved(mo))
|
||||
return;
|
||||
|
||||
//{ SRB2kart - Jawz
|
||||
if (mo->type == MT_JAWZ || mo->type == MT_JAWZ_DUD)
|
||||
{
|
||||
if (mo->health == 1)
|
||||
{
|
||||
// This Item Damage
|
||||
S_StartSound(mo, mo->info->deathsound);
|
||||
P_KillMobj(mo, NULL, NULL, DMG_NORMAL);
|
||||
|
||||
P_SetObjectMomZ(mo, 8*FRACUNIT, false);
|
||||
P_InstaThrust(mo, R_PointToAngle2(mo->x, mo->y, mo->x + xmove, mo->y + ymove)+ANGLE_90, 16*FRACUNIT);
|
||||
}
|
||||
}
|
||||
//}
|
||||
else if (mo->flags & MF_MISSILE)
|
||||
if (mo->flags & MF_MISSILE)
|
||||
{
|
||||
// explode a missile
|
||||
if (P_CheckSkyHit(mo))
|
||||
|
|
@ -1671,7 +1657,7 @@ void P_XYMovement(mobj_t *mo)
|
|||
{
|
||||
boolean walltransferred = false;
|
||||
|
||||
if (player || mo->flags & MF_SLIDEME)
|
||||
//if (player || mo->flags & MF_SLIDEME)
|
||||
{ // try to slide along it
|
||||
// Wall transfer part 1.
|
||||
pslope_t *transferslope = NULL;
|
||||
|
|
@ -1745,23 +1731,32 @@ void P_XYMovement(mobj_t *mo)
|
|||
fx->scale = mo->scale;
|
||||
}
|
||||
|
||||
if (mo->type == MT_ORBINAUT) // Orbinaut speed decreasing
|
||||
switch (mo->type)
|
||||
{
|
||||
if (mo->health > 1)
|
||||
{
|
||||
S_StartSound(mo, mo->info->attacksound);
|
||||
mo->health--;
|
||||
mo->threshold = 0;
|
||||
}
|
||||
else if (mo->health == 1)
|
||||
{
|
||||
// This Item Damage
|
||||
S_StartSound(mo, mo->info->deathsound);
|
||||
P_KillMobj(mo, NULL, NULL, DMG_NORMAL);
|
||||
case MT_ORBINAUT: // Orbinaut speed decreasing
|
||||
if (mo->health > 1)
|
||||
{
|
||||
S_StartSound(mo, mo->info->attacksound);
|
||||
mo->health--;
|
||||
mo->threshold = 0;
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
|
||||
P_SetObjectMomZ(mo, 8*FRACUNIT, false);
|
||||
P_InstaThrust(mo, R_PointToAngle2(mo->x, mo->y, mo->x + xmove, mo->y + ymove)+ANGLE_90, 16*FRACUNIT);
|
||||
}
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_DUD:
|
||||
if (mo->health == 1)
|
||||
{
|
||||
// This Item Damage
|
||||
S_StartSound(mo, mo->info->deathsound);
|
||||
P_KillMobj(mo, NULL, NULL, DMG_NORMAL);
|
||||
|
||||
P_SetObjectMomZ(mo, 8*FRACUNIT, false);
|
||||
P_InstaThrust(mo, R_PointToAngle2(mo->x, mo->y, mo->x + xmove, mo->y + ymove)+ANGLE_90, 16*FRACUNIT);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Bubble bounce
|
||||
|
|
@ -6666,7 +6661,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
break;
|
||||
case KITEM_SPB:
|
||||
case KITEM_SHRINK:
|
||||
indirectitemcooldown = 20*TICRATE;
|
||||
K_SetItemCooldown(mobj->threshold, 20*TICRATE);
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
mobj->sprite = SPR_ITEM;
|
||||
|
|
@ -6739,40 +6734,45 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
}
|
||||
else
|
||||
{
|
||||
fixed_t finalspeed = mobj->movefactor;
|
||||
const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy);
|
||||
fixed_t thrustamount = 0;
|
||||
fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction;
|
||||
mobj_t *ghost = P_SpawnGhostMobj(mobj);
|
||||
ghost->colorized = true; // already has color!
|
||||
|
||||
if (!grounded)
|
||||
{
|
||||
// No friction in the air
|
||||
frictionsafety = FRACUNIT;
|
||||
}
|
||||
|
||||
mobj->angle = K_MomentumAngle(mobj);
|
||||
if (mobj->health <= 5)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 5; i >= mobj->health; i--)
|
||||
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
|
||||
}
|
||||
|
||||
if (currentspeed >= finalspeed)
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
// Thrust as if you were at top speed, slow down naturally
|
||||
thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
|
||||
// Thrust to immediately get to top speed
|
||||
thrustamount = beatfriction + FixedDiv(finalspeed - currentspeed, frictionsafety);
|
||||
}
|
||||
fixed_t finalspeed = mobj->movefactor;
|
||||
const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy);
|
||||
fixed_t thrustamount = 0;
|
||||
fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction;
|
||||
|
||||
P_Thrust(mobj, mobj->angle, thrustamount);
|
||||
if (!grounded)
|
||||
{
|
||||
// No friction in the air
|
||||
frictionsafety = FRACUNIT;
|
||||
}
|
||||
|
||||
if (mobj->health <= 5)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 5; i >= mobj->health; i--)
|
||||
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
|
||||
}
|
||||
|
||||
if (currentspeed >= finalspeed)
|
||||
{
|
||||
// Thrust as if you were at top speed, slow down naturally
|
||||
thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
|
||||
// Thrust to immediately get to top speed
|
||||
thrustamount = beatfriction + FixedDiv(finalspeed - currentspeed, frictionsafety);
|
||||
}
|
||||
|
||||
P_Thrust(mobj, mobj->angle, thrustamount);
|
||||
}
|
||||
|
||||
if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true))
|
||||
K_DoPogoSpring(mobj, 0, 1);
|
||||
|
|
@ -6911,8 +6911,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->threshold--;
|
||||
break;
|
||||
case MT_SPB:
|
||||
indirectitemcooldown = 20*TICRATE;
|
||||
/* FALLTHRU */
|
||||
{
|
||||
Obj_SPBThink(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_MANTARING:
|
||||
{
|
||||
Obj_MantaRingThink(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_BALLHOG:
|
||||
{
|
||||
mobj_t *ghost = P_SpawnGhostMobj(mobj);
|
||||
|
|
@ -9274,6 +9281,11 @@ static boolean P_FuseThink(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj);
|
||||
return false;
|
||||
}
|
||||
case MT_SPB:
|
||||
{
|
||||
Obj_SPBExplode(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_PLAYER:
|
||||
break; // don't remove
|
||||
default:
|
||||
|
|
@ -9310,6 +9322,8 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetTarget(&mobj->hnext, NULL);
|
||||
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev))
|
||||
P_SetTarget(&mobj->hprev, NULL);
|
||||
if (mobj->itnext && P_MobjWasRemoved(mobj->itnext))
|
||||
P_SetTarget(&mobj->itnext, NULL);
|
||||
|
||||
if (mobj->flags & MF_NOTHINK)
|
||||
return;
|
||||
|
|
@ -10710,6 +10724,8 @@ void P_RemoveMobj(mobj_t *mobj)
|
|||
}
|
||||
}
|
||||
|
||||
P_SetTarget(&mobj->itnext, NULL);
|
||||
|
||||
// DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error.
|
||||
#ifdef SCRAMBLE_REMOVED
|
||||
// Invalidate mobj_t data to cause crashes if accessed!
|
||||
|
|
|
|||
|
|
@ -269,6 +269,9 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEUINT8(save_p, players[i].driftboost);
|
||||
WRITEUINT8(save_p, players[i].strongdriftboost);
|
||||
|
||||
WRITEUINT16(save_p, players[i].gateBoost);
|
||||
WRITEUINT8(save_p, players[i].gateSound);
|
||||
|
||||
WRITESINT8(save_p, players[i].aizdriftstrat);
|
||||
WRITEINT32(save_p, players[i].aizdrifttilt);
|
||||
WRITEINT32(save_p, players[i].aizdriftturn);
|
||||
|
|
@ -563,6 +566,9 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].driftboost = READUINT8(save_p);
|
||||
players[i].strongdriftboost = READUINT8(save_p);
|
||||
|
||||
players[i].gateBoost = READUINT16(save_p);
|
||||
players[i].gateSound = READUINT8(save_p);
|
||||
|
||||
players[i].aizdriftstrat = READSINT8(save_p);
|
||||
players[i].aizdrifttilt = READINT32(save_p);
|
||||
players[i].aizdriftturn = READINT32(save_p);
|
||||
|
|
@ -4558,7 +4564,8 @@ static void P_NetArchiveMisc(boolean resending)
|
|||
WRITEFIXED(save_p, battleovertime.z);
|
||||
|
||||
WRITEUINT32(save_p, wantedcalcdelay);
|
||||
WRITEUINT32(save_p, indirectitemcooldown);
|
||||
for (i = 0; i < NUMKARTITEMS-1; i++)
|
||||
WRITEUINT32(save_p, itemCooldowns[i]);
|
||||
WRITEUINT32(save_p, mapreset);
|
||||
|
||||
WRITEUINT8(save_p, spectateGriefed);
|
||||
|
|
@ -4721,7 +4728,8 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
|||
battleovertime.z = READFIXED(save_p);
|
||||
|
||||
wantedcalcdelay = READUINT32(save_p);
|
||||
indirectitemcooldown = READUINT32(save_p);
|
||||
for (i = 0; i < NUMKARTITEMS-1; i++)
|
||||
itemCooldowns[i] = READUINT32(save_p);
|
||||
mapreset = READUINT32(save_p);
|
||||
|
||||
spectateGriefed = READUINT8(save_p);
|
||||
|
|
|
|||
|
|
@ -4022,6 +4022,8 @@ static void P_InitPlayers(void)
|
|||
|
||||
static void P_InitGametype(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
spectateGriefed = 0;
|
||||
K_CashInPowerLevels(); // Pushes power level changes even if intermission was skipped
|
||||
|
||||
|
|
@ -4046,7 +4048,10 @@ static void P_InitGametype(void)
|
|||
}
|
||||
|
||||
wantedcalcdelay = wantedfrequency*2;
|
||||
indirectitemcooldown = 0;
|
||||
|
||||
for (i = 0; i < NUMKARTITEMS-1; i++)
|
||||
itemCooldowns[i] = 0;
|
||||
|
||||
mapreset = 0;
|
||||
|
||||
thwompsactive = false;
|
||||
|
|
@ -4074,6 +4079,9 @@ static void P_InitGametype(void)
|
|||
|
||||
G_RecordDemo(buf);
|
||||
}
|
||||
|
||||
// Started a game? Move on to the next jam when you go back to the title screen
|
||||
CV_SetValue(&cv_menujam_update, 1);
|
||||
}
|
||||
|
||||
/** Loads a level from a lump or external wad.
|
||||
|
|
|
|||
|
|
@ -1925,7 +1925,7 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
player->startboost = 125;
|
||||
|
||||
K_SpawnDriftBoostExplosion(player, 4);
|
||||
K_SpawnDriftElectricSparks(player);
|
||||
K_SpawnDriftElectricSparks(player, SKINCOLOR_SILVER, false);
|
||||
|
||||
rainbowstartavailable = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -683,8 +683,7 @@ void P_Ticker(boolean run)
|
|||
if (exitcountdown > 1)
|
||||
exitcountdown--;
|
||||
|
||||
if (indirectitemcooldown > 0)
|
||||
indirectitemcooldown--;
|
||||
K_RunItemCooldowns();
|
||||
|
||||
K_BossInfoTicker();
|
||||
|
||||
|
|
@ -768,6 +767,11 @@ void P_Ticker(boolean run)
|
|||
K_TimerInit();
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
G_CopyTiccmd(&players[i].oldcmd, &players[i].cmd, 1);
|
||||
}
|
||||
|
||||
// Z_CheckMemCleanup();
|
||||
}
|
||||
|
||||
|
|
|
|||
19
src/p_user.c
19
src/p_user.c
|
|
@ -2218,7 +2218,7 @@ void P_MovePlayer(player_t *player)
|
|||
player->drawangle -= ANGLE_22h;
|
||||
player->mo->rollangle = 0;
|
||||
player->glanceDir = 0;
|
||||
player->pflags &= ~PF_LOOKDOWN;
|
||||
player->pflags &= ~PF_GAINAX;
|
||||
}
|
||||
else if ((player->pflags & PF_FAULT) || (player->spinouttimer > 0))
|
||||
{
|
||||
|
|
@ -2592,7 +2592,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
|||
if (mo->type == MT_SPB) // If you destroy a SPB, you don't get the luxury of a cooldown.
|
||||
{
|
||||
spbplace = -1;
|
||||
indirectitemcooldown = 0;
|
||||
itemCooldowns[KITEM_SPB - 1] = 0;
|
||||
}
|
||||
|
||||
if (mo->flags & MF_BOSS) //don't OHKO bosses nor players!
|
||||
|
|
@ -4186,7 +4186,7 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
else if (cmd->buttons & BT_ACCELERATE)
|
||||
{
|
||||
if (!player->exiting && !(player->pflags & PF_ACCELDOWN))
|
||||
if (!player->exiting && !(player->oldcmd.buttons & BT_ACCELERATE))
|
||||
{
|
||||
player->kickstartaccel = 0;
|
||||
}
|
||||
|
|
@ -4394,19 +4394,6 @@ void P_PlayerThink(player_t *player)
|
|||
P_DoBubbleBreath(player); // Spawn Sonic's bubbles
|
||||
P_CheckInvincibilityTimer(player); // Spawn Invincibility Sparkles
|
||||
|
||||
// check for buttons
|
||||
if (cmd->buttons & BT_ACCELERATE)
|
||||
player->pflags |= PF_ACCELDOWN;
|
||||
else
|
||||
player->pflags &= ~PF_ACCELDOWN;
|
||||
|
||||
if (cmd->buttons & BT_BRAKE)
|
||||
player->pflags |= PF_BRAKEDOWN;
|
||||
else
|
||||
player->pflags &= ~PF_BRAKEDOWN;
|
||||
|
||||
// PF_LOOKDOWN handled in K_KartMoveAnimation
|
||||
|
||||
// Counters, time dependent power ups.
|
||||
// Time Bonus & Ring Bonus count settings
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
|
|||
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
|
||||
void R_PlaneBounds(visplane_t *plane);
|
||||
|
||||
size_t R_FlatDimensionsFromLumpSize(size_t size);
|
||||
void R_CheckFlatLength(size_t size);
|
||||
boolean R_CheckPowersOfTwo(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -656,6 +656,44 @@ boolean R_CheckPowersOfTwo(void)
|
|||
return ds_powersoftwo;
|
||||
}
|
||||
|
||||
//
|
||||
// R_FlatDimensionsFromLumpSize
|
||||
//
|
||||
// Returns the flat's square size from its lump length.
|
||||
//
|
||||
size_t R_FlatDimensionsFromLumpSize(size_t size)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
return 2048;
|
||||
|
||||
case 1048576: // 1024x1024 lump
|
||||
return 1024;
|
||||
|
||||
case 262144:// 512x512 lump
|
||||
return 512;
|
||||
|
||||
case 65536: // 256x256 lump
|
||||
return 256;
|
||||
|
||||
case 16384: // 128x128 lump
|
||||
return 128;
|
||||
|
||||
case 1024: // 32x32 lump
|
||||
return 32;
|
||||
|
||||
case 256: // 16x16 lump
|
||||
return 16;
|
||||
|
||||
case 64: // 8x8 lump
|
||||
return 8;
|
||||
|
||||
default: // 64x64 lump
|
||||
return 64;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_CheckFlatLength
|
||||
//
|
||||
|
|
@ -707,6 +745,20 @@ void R_CheckFlatLength(size_t size)
|
|||
nflatshiftup = 11;
|
||||
ds_flatwidth = ds_flatheight = 32;
|
||||
break;
|
||||
case 256: // 16x16 lump
|
||||
nflatmask = 0xF0;
|
||||
nflatxshift = 28;
|
||||
nflatyshift = 24;
|
||||
nflatshiftup = 12;
|
||||
ds_flatwidth = ds_flatheight = 16;
|
||||
break;
|
||||
case 64: // 8x8 lump
|
||||
nflatmask = 0x38;
|
||||
nflatxshift = 29;
|
||||
nflatyshift = 26;
|
||||
nflatshiftup = 13;
|
||||
ds_flatwidth = ds_flatheight = 8;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
nflatmask = 0xFC0;
|
||||
nflatxshift = 26;
|
||||
|
|
@ -774,30 +826,7 @@ Rloadflats (INT32 i, INT32 w)
|
|||
W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0);
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
switch (lumplength)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
flatsize = 2048;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
flatsize = 1024;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
flatsize = 512;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
flatsize = 256;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
flatsize = 128;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
flatsize = 32;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
flatsize = 64;
|
||||
break;
|
||||
}
|
||||
flatsize = R_FlatDimensionsFromLumpSize(lumplength);
|
||||
|
||||
//CONS_Printf("\n\"%s\" is a flat, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),flatsize,flatsize);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
|
|
|||
12
src/sounds.c
12
src/sounds.c
|
|
@ -1118,6 +1118,18 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
// Shrink laser beam
|
||||
{"beam01", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// SPB seeking
|
||||
{"spbska", false, 32, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"spbskb", false, 32, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"spbskc", false, 32, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// Juicebox for SPB
|
||||
{"gate01", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"gate02", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"gate03", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"gate04", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
{"gate05", false, 32, 64, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
||||
// SRB2Kart - Engine sounds
|
||||
// Engine class A
|
||||
{"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""},
|
||||
|
|
|
|||
12
src/sounds.h
12
src/sounds.h
|
|
@ -1183,6 +1183,18 @@ typedef enum
|
|||
// Shrink laser
|
||||
sfx_beam01,
|
||||
|
||||
// SPB seeking
|
||||
sfx_spbska,
|
||||
sfx_spbskb,
|
||||
sfx_spbskc,
|
||||
|
||||
// Juicebox for SPB
|
||||
sfx_gate01,
|
||||
sfx_gate02,
|
||||
sfx_gate03,
|
||||
sfx_gate04,
|
||||
sfx_gate05,
|
||||
|
||||
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
|
||||
// Engine class A - Low Speed, Low Weight
|
||||
sfx_krta00,
|
||||
|
|
|
|||
|
|
@ -1236,19 +1236,19 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum)
|
|||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
lflatsize = 2048;
|
||||
flatshift = 10;
|
||||
flatshift = 11;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
lflatsize = 1024;
|
||||
flatshift = 9;
|
||||
flatshift = 10;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
lflatsize = 512;
|
||||
flatshift = 8;
|
||||
flatshift = 9;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
lflatsize = 256;
|
||||
flatshift = 7;
|
||||
flatshift = 8;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
lflatsize = 128;
|
||||
|
|
@ -1258,6 +1258,14 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum)
|
|||
lflatsize = 32;
|
||||
flatshift = 5;
|
||||
break;
|
||||
case 256: // 16x16 lump
|
||||
lflatsize = 16;
|
||||
flatshift = 4;
|
||||
break;
|
||||
case 64: // 8x8 lump
|
||||
lflatsize = 8;
|
||||
flatshift = 3;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
lflatsize = 64;
|
||||
flatshift = 6;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue