Merge pull request 'Air Drop' (#125) from AirDrop into blankart-dev

Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/125
This commit is contained in:
NepDisk 2025-09-22 23:25:34 +02:00
commit 093b17987f
25 changed files with 349 additions and 30 deletions

View file

@ -86,6 +86,7 @@ option(SRB2_CONFIG_TRACY "Compile with Tracy profiling enabled" OFF)
option(SRB2_CONFIG_ASAN "Compile with AddressSanitizer (libasan)." OFF)
set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.")
option(SRB2_CONFIG_LTO "Enable link time optimizations, improves performance at the cost of longer link times." ON)
option(SRB2_CONFIG_TIDY "Enable clang tiny, checks compiled code for issues at the cost of longer compile times." OFF)
if(SRB2_CONFIG_ENABLE_TESTS)
# https://github.com/catchorg/Catch2

View file

@ -64,6 +64,10 @@ if(SRB2_CONFIG_ASAN)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
endif()
if(SRB2_CONFIG_TIDY)
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=*")
endif()
add_subdirectory(blua)
add_subdirectory(blan)
add_subdirectory(sdl)

View file

@ -160,6 +160,7 @@ static void KartChaining_OnChange(void);
static void KartSlipdash_OnChange(void);
static void KartSlopeBoost_OnChange(void);
static void KartDrafting_OnChange(void);
static void KartAirDrop_OnChange(void);
static void KartItemBreaker_OnChange(void);
static void KartInvinType_OnChange(void);
static void KartBumpSpark_OnChange(void);
@ -548,6 +549,8 @@ consvar_t cv_kartdrafting_closedraft = CVAR_INIT ("kartdrafting_closedraft", "Of
consvar_t cv_kartdrafting_closedeadzone = CVAR_INIT ("kartdrafting_closedeadzone", "640", CV_NETVAR|CV_CHEAT, CV_Unsigned, NULL);
consvar_t cv_kartdrafting_basedistance = CVAR_INIT ("kartdrafting_basedistance", "2560", CV_NETVAR|CV_CHEAT, CV_Unsigned, NULL);
consvar_t cv_kartairdrop = CVAR_INIT ("kartairdrop", "No", CV_NETVAR|CV_CALL|CV_NOINIT, CV_YesNo, KartAirDrop_OnChange);
// Invincibility modifiers
static CV_PossibleValue_t invintype_cons_t[] = {{0, "Legacy"}, {1, "Alternative"}, {0, NULL}};
consvar_t cv_kartinvintype = CVAR_INIT ("kartinvintype", "Legacy", CV_NETVAR|CV_CALL, invintype_cons_t, KartInvinType_OnChange);
@ -7595,6 +7598,40 @@ static void KartDrafting_OnChange(void)
}
}
static void KartAirDrop_OnChange(void)
{
if (K_CanChangeRules() == false)
{
return;
}
if (!K_AirDropActive() && cv_kartairdrop.value)
{
if (leveltime < starttime)
{
airdropactive = true;
CONS_Printf(M_GetText("Air Drop has been turned \"On\".\n"));
}
else
{
CONS_Printf(M_GetText("Air Drop will be turned \"On\" Next Round.\n"));
}
}
else if (K_AirDropActive() && !cv_kartairdrop.value)
{
if (leveltime < starttime)
{
airdropactive = false;
CONS_Printf(M_GetText("Drafting has been turned \"Off\".\n"));
}
else
{
CONS_Printf(M_GetText("Drafting will be turned \"Off\" next round.\n"));
}
}
}
static void KartItemBreaker_OnChange(void)
{
if (K_CanChangeRules() == false)

View file

@ -198,6 +198,8 @@ extern consvar_t cv_kartinvindistmul;
extern consvar_t cv_kartinvin_maxtime;
extern consvar_t cv_kartinvin_midtime;
extern consvar_t cv_kartairdrop;
extern consvar_t cv_encorevotes;
extern consvar_t cv_votetime;

View file

@ -683,12 +683,16 @@ struct player_t
SINT8 ringmax; // maximum rings
UINT8 pickuprings; // Number of rings being picked up before added to the counter (prevents rings from being deleted forever over 20)
UINT8 ringdelay; // (0 to 3) - 3 tic delay between every ring usage
UINT8 ringlock; // Timer for automatic handeling of ringlock
UINT16 ringboost; // Ring boost timer
UINT16 ringtime; // The current Ring boost timer if it wasn't capped. Used for spam prevention measures.
UINT16 superring; // Spawn rings on top of you every tic!
UINT8 nextringaward; // When should we spawn our next superring ring?
UINT8 ringvolume; // When consuming lots of rings, lower the sound a little.
UINT8 ringtransparency; // When consuming lots of rings, fade out the rings again.
UINT8 ringtransparency; // When consuming lots of rings, fade out the rings again.
UINT8 airdroptime; // Tracks how long airdrop has been active, used for delay before airdrop kicks in.
boolean ringdrop; // Set when having ringdrop applied.
UINT8 curshield; // see kartshields_t
UINT8 bubblecool; // Bubble Shield use cooldown

View file

@ -1859,6 +1859,7 @@ static struct { const char *name; consvar_t *var; } HIDDENVARS[] = {
{ "DUMMYATTACKINGSLIPDASH", &cv_dummyattackingslipdash },
{ "DUMMYATTACKINGPURPLEDRIFT", &cv_dummyattackingpurpledrift },
{ "DUMMYATTACKINGSLOPEBOOST", &cv_dummyattackingslopeboost },
{ "DUMMYATTACKINGAIRDROP", &cv_dummyattackingairdrop },
{ "DUMMYATTACKINGBUMPSPARK", &cv_dummyattackingbumpspark },
{ "DUMMYSTAFF", &cv_dummystaff },
{ "DUMMYMULTIPLAYER", &cv_dummymultiplayer },

View file

@ -1597,7 +1597,8 @@ struct int_const_s const INT_CONST[] = {
{"TMBOT_NORUBBERBAND",TMBOT_NORUBBERBAND},
{"TMBOT_NOCONTROL",TMBOT_NOCONTROL},
{"TMBOT_FORCEDIR",TMBOT_FORCEDIR},
//{"TMBOT_FASTFALL",TMBOT_FASTFALL},
{"TMBOT_AIRDROP",TMBOT_AIRDROP},
{"TMBOT_FASTFALL",TMBOT_AIRDROP},
// textmapbottrick_t
/*

View file

@ -103,7 +103,7 @@ extern "C" {
// Special Hashing.
//#define NOFILEHASH
//#define NOVERIFYIWADS
#define NOVERIFYIWADS
// Uncheck this to compile debugging code
//#define RANGECHECK

View file

@ -112,7 +112,7 @@ demoghost *ghosts = NULL;
// DEMO RECORDING
//
#define DEMOVERSION 0x000B
#define DEMOVERSION 0x000C
#define DEMOHEADER "\xF0" "BlanReplay" "\x0F"
#define DF_GHOST 0x01 // This demo contains ghost data too!
@ -2740,6 +2740,8 @@ void G_BeginRecording(void)
raflags |= RAF_PURPLEDRIFT;
if (cv_dummyattackingslopeboost.value)
raflags |= RAF_SLOPEBOOST;
if (cv_dummyattackingairdrop.value)
raflags |= RAF_AIRDROP;
if (cv_dummyattackingbumpspark.value == BUMPSPARK_ALL)
raflags |= RAF_BUMPSPARK;
if (cv_dummyattackingbumpspark.value == BUMPSPARK_NOCHARGE)
@ -3832,6 +3834,7 @@ void G_AddGhost(char *defdemoname)
CLEANUP(Z_Pfree) char *pdemoname = NULL;
const char *n;
UINT64 demohash;
UINT32 raflags;
demoghost *gh;
UINT8 flags;
CLEANUP(Z_Pfree) UINT8 *buffer = NULL;
@ -3895,6 +3898,7 @@ void G_AddGhost(char *defdemoname)
flags = header.demoflags;
raflags = header.raflags;
if (!(flags & DF_GHOST))
{
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: No ghost data in this demo.\n"), pdemoname);
@ -3913,6 +3917,40 @@ void G_AddGhost(char *defdemoname)
return;
}
// Check RA flags.
{
UINT32 ourraflags = 0;
UINT16 demoversion = header.demoversion;
if (cv_dummyattackingrings.value)
ourraflags |= RAF_RINGS;
if (cv_dummyattackingstacking.value)
ourraflags |= RAF_STACKING;
if (cv_dummyattackingchaining.value)
ourraflags |= RAF_CHAINING;
if (cv_dummyattackingslipdash.value)
ourraflags |= RAF_SLIPDASH;
if (cv_dummyattackingpurpledrift.value)
ourraflags |= RAF_PURPLEDRIFT;
if (cv_dummyattackingslopeboost.value)
ourraflags |= RAF_SLOPEBOOST;
if (cv_dummyattackingairdrop.value)
ourraflags |= RAF_AIRDROP;
if (demoversion <= 0x000B)
{
ourraflags &= ~RAF_AIRDROP;
ourraflags &= ~RAF_BUMPDRIFT;
ourraflags &= ~RAF_BUMPSPARK;
}
if (ourraflags != raflags)
{
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Replay doesn't match current RA mode.\n"), pdemoname);
return;
}
}
demoplayer_t *plr = &header.playerdata[0];
// any invalidating flags?

View file

@ -41,8 +41,9 @@ typedef enum
RAF_SLIPDASH = 1<<3,
RAF_PURPLEDRIFT = 1<<4,
RAF_SLOPEBOOST = 1<<5,
RAF_BUMPDRIFT = 1<<6,
RAF_BUMPSPARK = 1<<7,
RAF_AIRDROP = 1<<6,
RAF_BUMPDRIFT = 1<<7,
RAF_BUMPSPARK = 1<<8,
// up to 1<<31 is free
} raflags_t;

View file

@ -483,12 +483,13 @@ SINT8 G_RecordPresetIndex(void)
boolean slipdash = cv_dummyattackingslipdash.value;
boolean purpledrift = cv_dummyattackingpurpledrift.value;
boolean slopeboost = cv_dummyattackingslopeboost.value;
boolean bumpspark = cv_dummyattackingbumpspark.value;
boolean airdrop = cv_dummyattackingairdrop.value;
UINT8 bumpspark = cv_dummyattackingbumpspark.value;
if (!rings && !stacking && !chaining && !slipdash && !purpledrift && !slopeboost && !bumpspark)
if (!rings && !stacking && !chaining && !slipdash && !purpledrift && !slopeboost && !airdrop && (bumpspark == BUMPSPARK_NONE))
return RP_KART;
if (stacking && chaining && slopeboost && !rings && !slipdash && !purpledrift && (bumpspark == BUMPSPARK_ALL))
if (stacking && chaining && slopeboost && airdrop && !rings && !slipdash && !purpledrift && (bumpspark == BUMPSPARK_ALL))
return RP_TECH;
if (rings && stacking && chaining && slipdash && purpledrift && slopeboost && (bumpspark == BUMPSPARK_NOCHARGE))

View file

@ -1640,6 +1640,26 @@ void K_BotTicker(const player_t *player)
forcedDir = true;
}
if (P_IsObjectOnGround(player->mo) == false)
{
if (player->airdroptime == 0
&& K_AirDropActive()
&& !P_PlayerInPain(player)
&& !player->loop.radius
&& !(player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
&& !player->respawn)
{
if (botController != nullptr && (botController->flags & TMBOT_AIRDROP) == TMBOT_AIRDROP)
{
// Air Drop!
bd->brakedown = true;
return;
}
}
//return; // Don't allow bots to turn in the air.
}
if (forcedDir == true)
{
destangle = R_PointToAngle2(player->mo->x, player->mo->y, bd->predict.x, bd->predict.y);

View file

@ -2363,7 +2363,7 @@ void K_SetScoreboardModStatus(const char *name, SINT8 active)
CONS_Alert(CONS_WARNING, "Server mod '%s' does not exist so status cannot be changed.\n", name);
}
#define BASEMODS 12
#define BASEMODS 14
static void K_DrawServerMods(INT32 x, INT32 y)
{
UINT8 i, j;
@ -2380,6 +2380,8 @@ static void K_DrawServerMods(INT32 x, INT32 y)
{"Chain Offroad", 0, &cv_kartchainingoffroad, -1, true},
{"Slope Boost", 0, NULL, K_PurpleDriftActive() > 0, true},
{"Drafting", 0, NULL, K_DraftingActive() > 0, true},
{"Air Drop", 0, NULL, K_AirDropActive() > 0, true},
{"Bump Spark", 0, &cv_kartbumpspark, -1, true},
{"Bump Drift", 0, NULL, K_GetBumpSpark() > 0, true},
{"Bump Spark", 0, NULL, K_GetBumpSpark() == BUMPSPARK_ALL, true},
{"Bump Spring", 0, &cv_kartbumpspring, -1, true},

View file

@ -364,6 +364,8 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartchainingoffroad);
CV_RegisterVar(&cv_kartchainingsound);
CV_RegisterVar(&cv_kartairdrop);
CV_RegisterVar(&cv_kartitembreaker);
//CV_RegisterVar(&cv_kartwalltransfer);
@ -6602,11 +6604,7 @@ static void K_HandleRingDeincrement(player_t *player, boolean chainnerf)
finalringtimer += subring;
}
if (player->ringboost - finalringtimer > player->chaintimer)
{
// Cap this to prevent displacement between chaintimer and ringtimer.
player->chaintimer = min(player->ringboost, (TICRATE - TICRATE/4));
}
player->chaintimer = max(player->ringboost, player->chaintimer);
}
player->ringboost = max(0, player->ringboost - finalringtimer);
@ -6643,6 +6641,103 @@ void K_AwardScaledPlayerRings(player_t *player, SINT8 mode)
K_AwardPlayerRings(player, awardamount, (mode == ASR_SUPERRING) ? true : false);
}
void K_SpawnFallLines(player_t *player, boolean ringdrop)
{
fixed_t rand_x;
fixed_t rand_y;
fixed_t rand_z;
rand_z = player->mo->z + player->mo->height + (16 * player->mo->scale) + (P_RandomRange(-15,15) * player->mo->scale);
rand_y = player->mo->y + (P_RandomRange(-25,25) * player->mo->scale);
rand_x = player->mo->x + (P_RandomRange(-25,25) * player->mo->scale);
mobj_t *fast = P_SpawnMobj(rand_x, rand_y, rand_z, MT_FASTLINE);
P_SetTarget(&fast->target, player->mo);
fast->momx = 3*player->mo->momx/4;
fast->momy = 3*player->mo->momy/4;
fast->momz = 3*P_GetMobjZMovement(player->mo)/4;
P_SetScale(fast, fast->scale/4);
fast->angle = player->mo->angle+ANGLE_90;
fast->rollangle = ANGLE_90;
fast->colorized = true;
if (ringdrop)
{
fast->color = SKINCOLOR_CROCODILE;
fast->renderflags |= RF_TRANS10;
}
else
fast->color = SKINCOLOR_IVORY;
fast->renderflags |= RF_ADD;
K_MatchGenericExtraFlags(fast, player->mo);
}
void K_AirDrop(player_t *player, ticcmd_t *cmd)
{
if ((player->cmd.buttons & BT_BRAKE)
&& K_AirDropActive()
&& !P_IsObjectOnGround(player->mo)
&& !P_PlayerInPain(player)
&& !player->loop.radius
&& !(player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
&& !player->respawn)
{
SINT8 airbrakedelay = (player->rings > 0) ? TICRATE/4 : TICRATE/3;
if (player->airdroptime < airbrakedelay)
{
if (player->rings > 0)
{
player->ringlock = 6;
}
player->ringdrop = false;
}
else
{
if (!player->ringdelay && player->rings > 0)
{
mobj_t *ring = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_RING);
P_SetMobjState(ring, S_FASTRING1);
ring->renderflags |= RF_ADD;
ring->renderflags |= RF_TRANS60;
ring->colorized = true;
ring->color = SKINCOLOR_SILVER;
ring->extravalue1 = 18; // Ring use animation timer
ring->extravalue2 = 1; // Ring use animation flag
ring->extravalue3 = 1; // Ring airdrop use flag
ring->shadowscale = 0;
P_SetTarget(&ring->target, player->mo); // user
player->rings--;
player->ringdelay = 5;
player->ringlock = 6;
}
if (player->rings <= 0)
{
player->ringdrop = false;
}
K_SpawnFallLines(player, player->ringdrop);
player->mo->momz -= FixedMul(gravity, mapobjectscale)*P_MobjFlip(player->mo);
}
if (player->airdroptime < UINT8_MAX)
player->airdroptime++;
}
else
{
player->airdroptime = 0;
player->ringdrop = false;
}
}
// Returns the bumpspark value as an enum.
INT32 K_GetBumpSpark(void)
{
@ -6875,6 +6970,19 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
K_HandleRingDeincrement(player, chainingactive);
}
K_AirDrop(player, cmd);
if (player->ringlock)
{
player->chaintimer = max(player->chaintimer, player->ringboost);
player->ringlock--;
if (!player->ringlock)
player->pflags &= ~PF_RINGLOCK;
else
player->pflags |= PF_RINGLOCK;
}
if (!player->ringboost && !player->chaintimer)
player->ringtime = 0;
@ -9848,7 +9956,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|| ((K_GetKartInvinType() == KARTINVIN_ALTERN) && player->invincibilitytimer)
|| (player->growshrinktimer > 0)
|| player->flametimer
|| (leveltime < starttime)))
|| (leveltime < starttime)
|| (player->pflags & PF_RINGLOCK)))
player->itemflags |= IF_USERINGS;
else
player->itemflags &= ~IF_USERINGS;
@ -10975,6 +11084,17 @@ boolean K_DraftingActive(void)
return false;
}
boolean K_AirDropActive(void)
{
if (airdropactive)
{
// Air Drop is enabled!
return true;
}
return false;
}
boolean K_GetKartInvinType(void)
{
return invintype;

View file

@ -322,6 +322,7 @@ boolean K_ChainingActive(void);
boolean K_SlipdashActive(void);
boolean K_SlopeBoostActive(void);
boolean K_DraftingActive(void);
boolean K_AirDropActive(void);
boolean K_GetKartInvinType(void);
INT32 K_GetBumpSpark(void);
boolean K_BoostChain(player_t *player, INT32 timer, boolean chainsound);

View file

@ -4170,6 +4170,13 @@ static int lib_kDraftingActive(lua_State *L)
return 1;
}
// Checks if Air Drop is active.
static int lib_kAirDropActive(lua_State *L)
{
lua_pushboolean(L, K_AirDropActive());
return 1;
}
// Grabs the currently active invintype.
static int lib_kGetKartInvinType(lua_State *L)
{
@ -5273,6 +5280,7 @@ static luaL_Reg lib[] = {
{"K_SlipdashActive",lib_kSlipdashActive},
{"K_SlopeBoostActive",lib_kSlopeBoostActive},
{"K_DraftingActive",lib_kDraftingActive},
{"K_AirDropActive",lib_kAirDropActive},
{"K_GetBumpSpark",lib_kGetBumpSpark},
{"K_GetKartInvinType",lib_kGetKartInvinType},
{"K_UsingLegacyCheckpoints",lib_kUsingLegacyCheckpoints},

View file

@ -256,12 +256,15 @@ enum player_e
player_ringmax,
player_pickuprings,
player_ringdelay,
player_ringlock,
player_ringboost,
player_ringtime,
player_superring,
player_nextringaward,
player_ringvolume,
player_ringtransparency,
player_airdroptime,
player_ringdrop,
player_curshield,
player_bubblecool,
player_bubbleblowup,
@ -453,12 +456,15 @@ static const char *const player_opt[] = {
"ringmax",
"pickuprings",
"ringdelay",
"ringlock",
"ringboost",
"ringtime",
"superring",
"nextringaward",
"ringvolume",
"ringtransparency",
"airdroptime",
"ringdrop",
"curshield",
"bubblecool",
"bubbleblowup",
@ -854,6 +860,9 @@ static int player_get(lua_State *L)
case player_ringdelay:
lua_pushinteger(L, plr->ringdelay);
break;
case player_ringlock:
lua_pushinteger(L, plr->ringlock);
break;
case player_ringboost:
lua_pushinteger(L, plr->ringboost);
break;
@ -872,6 +881,12 @@ static int player_get(lua_State *L)
case player_ringtransparency:
lua_pushinteger(L, plr->ringtransparency);
break;
case player_airdroptime:
lua_pushinteger(L, plr->airdroptime);
break;
case player_ringdrop:
lua_pushinteger(L, plr->ringdrop);
break;
case player_curshield:
lua_pushinteger(L, plr->curshield);
break;
@ -1534,6 +1549,9 @@ static int player_set(lua_State *L)
case player_ringdelay:
plr->ringdelay = luaL_checkinteger(L, 3);
break;
case player_ringlock:
plr->ringlock = luaL_checkinteger(L, 3);
break;
case player_ringboost:
plr->ringboost = luaL_checkinteger(L, 3);
break;
@ -1552,6 +1570,12 @@ static int player_set(lua_State *L)
case player_ringtransparency:
plr->ringtransparency = luaL_checkinteger(L, 3);
break;
case player_airdroptime:
plr->airdroptime = luaL_checkinteger(L, 3);
break;
case player_ringdrop:
plr->ringdrop = luaL_checkinteger(L, 3);
break;
case player_curshield:
plr->curshield = luaL_checkinteger(L, 3);
break;

View file

@ -397,6 +397,8 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word,"draftingactive")) {
lua_pushinteger(L, draftingactive);
return 1;
} else if (fastcmp(word,"airdropactive")) {
lua_pushinteger(L, airdropactive);
} else if (fastcmp(word,"bumpsparkactive")) {
lua_pushinteger(L, bumpsparkactive);
return 1;

View file

@ -455,8 +455,10 @@ consvar_t cv_dummyattackingchaining = CVAR_INIT ("dummyattackingchaining", "Off"
consvar_t cv_dummyattackingslipdash = CVAR_INIT ("dummyattackingslipdash", "Off", CV_HIDEN|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange);
consvar_t cv_dummyattackingpurpledrift = CVAR_INIT ("dummyattackingpurpledrift", "Off", CV_HIDEN|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange);
consvar_t cv_dummyattackingslopeboost = CVAR_INIT ("dummyattackingslopeboost", "Off", CV_HIDEN|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange);
consvar_t cv_dummyattackingairdrop = CVAR_INIT ("dummyattackingairdrop", "Off", CV_HIDEN|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange);
static CV_PossibleValue_t dummybumpspark_cons_t[] = {{BUMPSPARK_NONE, "Off"}, {BUMPSPARK_NOCHARGE, "NoCharge"}, {BUMPSPARK_ALL, "On"}};
static CV_PossibleValue_t dummybumpspark_cons_t[] = {{BUMPSPARK_NONE, "Off"}, {BUMPSPARK_NOCHARGE, "NoCharge"}, {BUMPSPARK_ALL, "On"}, {0, NULL}};
consvar_t cv_dummyattackingbumpspark = CVAR_INIT ("dummyattackingbumpspark", "Off", CV_HIDEN|CV_CALL|CV_NOINIT, dummybumpspark_cons_t, Nextmap_OnChange);
static CV_PossibleValue_t dummygpdifficulty_cons_t[] = {{KARTSPEED_EASY, "Easy"}, {KARTSPEED_NORMAL, "Normal"}, {KARTSPEED_HARD, "Hard"}, {KARTSPEED_EXPERT, "Expert"}, {KARTGP_MASTER, "Master"}, {KARTGP_NIGHTMARE, "Nightmare"}, {0, NULL}};
@ -660,6 +662,7 @@ char *M_AppendGametypeAndModName(void)
ADD(cv_dummyattackingslipdash, "SD-")
ADD(cv_dummyattackingpurpledrift, "PD-")
ADD(cv_dummyattackingslopeboost, "SB-")
ADD(cv_dummyattackingairdrop, "AD-")
ADDEQUALS(cv_dummyattackingbumpspark, "BD-", BUMPSPARK_NOCHARGE)
ADDEQUALS(cv_dummyattackingbumpspark, "BS-", BUMPSPARK_ALL)
@ -2174,6 +2177,7 @@ void M_Init(void)
CV_RegisterVar(&cv_dummyattackingslipdash);
CV_RegisterVar(&cv_dummyattackingpurpledrift);
CV_RegisterVar(&cv_dummyattackingslopeboost);
CV_RegisterVar(&cv_dummyattackingairdrop);
CV_RegisterVar(&cv_dummyattackingbumpspark);
CV_RegisterVar(&cv_dummygpdifficulty);
@ -5741,7 +5745,7 @@ void MD_DrawTimeAttackMenu(void)
// Draw current RA preset mode.
{
const char *mode = "Unkown mode";
const char *mode = "Unknown mode";
if (preset == 0)
{
mode = "SRB2Kart Mode";
@ -5861,11 +5865,11 @@ INT32 MR_ReplayStaff(INT32 choice)
}
#define NUMPRESETS 3
static INT32 presets[NUMPRESETS][7] = {
//rings stacking chaining slipdash purpledrift slopeboost bumpspark
{ 0, 0, 0, 0, 0, 0, BUMPSPARK_NONE}, // SRB2Kart
{ 0, 1, 1, 0, 0, 1, BUMPSPARK_ALL}, // Tech
{ 1, 1, 1, 1, 1, 1, BUMPSPARK_NOCHARGE}, // BlanKart
static INT32 presets[NUMPRESETS][8] = {
//rings stacking chaining slipdash purpledrift slopeboost airdrop bumpspark
{ 0, 0, 0, 0, 0, 0, 0, BUMPSPARK_NONE }, // SRB2Kart
{ 0, 1, 1, 0, 0, 1, 1, BUMPSPARK_ALL }, // Tech
{ 1, 1, 1, 1, 1, 1, 1, BUMPSPARK_NOCHARGE }, // BlanKart
};
INT32 MR_TimeAttackPreset(INT32 arg)
@ -5880,8 +5884,9 @@ INT32 MR_TimeAttackPreset(INT32 arg)
CV_Set(&cv_dummyattackingslipdash, (boolean)preset[3] ? "On" : "Off");
CV_Set(&cv_dummyattackingpurpledrift, (boolean)preset[4] ? "On" : "Off");
CV_Set(&cv_dummyattackingslopeboost, (boolean)preset[5] ? "On" : "Off");
CV_Set(&cv_dummyattackingairdrop, preset[6] ? "On" : "Off");
switch(preset[6])
switch(preset[7])
{
case BUMPSPARK_ALL:
CV_Set(&cv_dummyattackingbumpspark, "On");

View file

@ -422,7 +422,7 @@ extern consvar_t cv_dummygpdifficulty, cv_dummygpencore, cv_dummygpcup;
extern consvar_t cv_dummymenuplayer, cv_dummyteam, cv_dummyspectate, cv_dummyscramble;
extern consvar_t cv_dummyattackingrings, cv_dummyattackingstacking, cv_dummyattackingchaining;
extern consvar_t cv_dummyattackingslipdash, cv_dummyattackingpurpledrift, cv_dummyattackingslopeboost;
extern consvar_t cv_dummyattackingbumpspark;
extern consvar_t cv_dummyattackingairdrop, cv_dummyattackingbumpspark;
extern consvar_t cv_dummystaff;
extern consvar_t cv_dummymultiplayer, cv_dummyip, cv_dummyname, cv_dummyfollower, cv_dummycolor;
extern consvar_t cv_dummyserverpage;

View file

@ -3170,11 +3170,27 @@ void A_AttractChase(mobj_t *actor)
if (actor->extravalue1 >= 21)
{
// Base add is 4 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true);
actor->target->player->ringtime += K_GetKartRingPower(actor->target->player, true);
if (actor->extravalue3 && !P_IsObjectOnGround(actor->target))
{
actor->target->momz -= (FixedMul(gravity, mapobjectscale))*P_MobjFlip(actor->target);
actor->target->player->ringboost += 5;
actor->target->player->ringtime += 5;
actor->target->player->ringdrop = true;
}
else
{
// Base add is 4 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true);
actor->target->player->ringtime += K_GetKartRingPower(actor->target->player, true);
}
S_StartSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume);
if (actor->extravalue3 && !P_IsObjectOnGround(actor->target))
{
actor->target->momz -= (FixedMul(gravity, mapobjectscale)/2)*P_MobjFlip(actor->target);
}
if (actor->target->player->rings <= 10)
{
S_StartSoundAtVolume(actor->target, sfx_ringlw, 255 - actor->target->player->rings*10);
@ -3199,6 +3215,7 @@ void A_AttractChase(mobj_t *actor)
( actor->target->height + offz )* P_MobjFlip(actor));
actor->extravalue1++;
}
}
else // Collecting
{

View file

@ -407,6 +407,7 @@ struct mobj_t
// Extra values are for internal use for whatever you want
INT32 extravalue1;
INT32 extravalue2;
INT32 extravalue3;
// Custom values are not to be altered by us!
// They are for SOCs to store things in.
@ -606,6 +607,7 @@ extern boolean slipdashactive;
extern boolean purpledriftactive;
extern boolean slopeboostactive;
extern boolean draftingactive;
extern boolean airdropactive;
extern UINT8 bumpsparkactive;
extern UINT16 bossdisabled;
extern boolean stoppedclock;

View file

@ -327,6 +327,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITESINT8(save->p, players[i].ringmax);
WRITEUINT8(save->p, players[i].pickuprings);
WRITEUINT8(save->p, players[i].ringdelay);
WRITEUINT8(save->p, players[i].ringlock);
WRITEUINT16(save->p, players[i].ringboost);
WRITEUINT16(save->p, players[i].ringtime);
WRITEUINT16(save->p, players[i].superring);
@ -334,6 +335,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT8(save->p, players[i].ringvolume);
WRITEUINT8(save->p, players[i].ringtransparency);
WRITEUINT8(save->p, players[i].airdroptime);
WRITEUINT8(save->p, players[i].ringdrop);
WRITEUINT8(save->p, players[i].curshield);
WRITEUINT8(save->p, players[i].bubblecool);
WRITEUINT8(save->p, players[i].bubbleblowup);
@ -680,6 +684,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].ringmax = READSINT8(save->p);
players[i].pickuprings = READUINT8(save->p);
players[i].ringdelay = READUINT8(save->p);
players[i].ringlock = READUINT8(save->p);
players[i].ringboost = READUINT16(save->p);
players[i].ringtime = READUINT16(save->p);;
players[i].superring = READUINT16(save->p);
@ -687,6 +692,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].ringvolume = READUINT8(save->p);
players[i].ringtransparency = READUINT8(save->p);
players[i].airdroptime = READUINT8(save->p);
players[i].ringdrop = READUINT8(save->p);
players[i].curshield = READUINT8(save->p);
players[i].bubblecool = READUINT8(save->p);
players[i].bubbleblowup = READUINT8(save->p);
@ -2095,6 +2103,7 @@ typedef enum
MD3_GRAVITY = 1,
MD3_MISCCAP = 1<<1,
MD3_BAKEDOFFSET = 1<<2,
MD3_EXTVAL3 = 1<<3,
} mobj_diff3_t;
typedef enum
@ -2410,6 +2419,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (mobj->bakexoff || mobj->bakeyoff || mobj->bakezoff || mobj->bakexpiv ||
mobj->bakeypiv || mobj->bakezpiv)
diff3 |= MD3_BAKEDOFFSET;
if (mobj->extravalue3)
diff3 |= MD3_EXTVAL3;
if (diff3 != 0)
diff2 |= MD2_MORE;
@ -2696,6 +2707,10 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
WRITEFIXED(save->p, mobj->bakeypiv);
WRITEFIXED(save->p, mobj->bakezpiv);
}
if (diff3 & MD3_EXTVAL3)
{
WRITEINT32(save->p, mobj->extravalue3);
}
WRITEUINT32(save->p, mobj->mobjnum);
}
@ -3995,6 +4010,10 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker, UINT8
mobj->bakexoff = mobj->bakeyoff = mobj->bakezoff = 0;
mobj->bakexpiv = mobj->bakeypiv = mobj->bakezpiv = 0;
}
if (diff3 & MD3_EXTVAL3)
{
mobj->extravalue3 = READINT32(save->p);
}
// Reset some non-synch values
mobj->sloperoll = 0;
@ -5298,6 +5317,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
WRITEUINT8(save->p, purpledriftactive);
WRITEUINT8(save->p, slopeboostactive);
WRITEUINT8(save->p, draftingactive);
WRITEUINT8(save->p, airdropactive);
WRITEUINT8(save->p, bumpsparkactive);
for (i = 0; i < 12; i++)
@ -5686,6 +5706,7 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
purpledriftactive = READUINT8(save->p);
slopeboostactive = READUINT8(save->p);
draftingactive = READUINT8(save->p);
airdropactive = READUINT8(save->p);
bumpsparkactive = READUINT8(save->p);
for (i = 0; i < 12; i++)

View file

@ -154,6 +154,7 @@ boolean slipdashactive;
boolean purpledriftactive;
boolean slopeboostactive;
boolean draftingactive;
boolean airdropactive;
UINT8 bumpsparkactive;
UINT16 bossdisabled;
boolean stoppedclock;
@ -8035,6 +8036,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
purpledriftactive = false;
slopeboostactive = false;
draftingactive = false;
airdropactive = false;
bumpsparkactive = 0;
if (cv_kartrings.value)
@ -8058,8 +8060,10 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
if (cv_kartdrafting.value)
draftingactive = true;
bumpsparkactive = (UINT8)cv_kartbumpspark.value;
if (cv_kartairdrop.value)
airdropactive = true;
bumpsparkactive = (UINT8)cv_kartbumpspark.value;
invintype = (UINT8)cv_kartinvintype.value;
// emerald hunt
@ -8150,6 +8154,8 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
purpledriftactive = true;
if (raflags & RAF_SLOPEBOOST)
slopeboostactive = true;
if (raflags & RAF_AIRDROP)
airdropactive = true;
if (raflags & RAF_BUMPSPARK)
bumpsparkactive = BUMPSPARK_ALL;
if (raflags & RAF_BUMPDRIFT)
@ -8163,7 +8169,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
chainingactive = cv_dummyattackingchaining.value;
slipdashactive = cv_dummyattackingslipdash.value;
slopeboostactive = cv_dummyattackingslopeboost.value;
airdropactive = cv_dummyattackingairdrop.value;
bumpsparkactive = (UINT8)(cv_dummyattackingbumpspark.value);
}
}

View file

@ -541,6 +541,7 @@ typedef enum
TMBOT_NORUBBERBAND = 1,
TMBOT_NOCONTROL = 1<<1,
TMBOT_FORCEDIR = 1<<2,
TMBOT_AIRDROP = 1<<3,
} textmapbotcontroller_t;
typedef enum