diff --git a/CMakeLists.txt b/CMakeLists.txt index 567ab0ee2..aac038881 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 07fc40d33..03cc0cb96 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 99618fa4a..f55104ec7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -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); @@ -546,6 +547,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); @@ -7593,6 +7596,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) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index a0d2ea124..4fb975046 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -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; diff --git a/src/d_player.h b/src/d_player.h index 04436637b..2b0a103c7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -683,12 +683,15 @@ 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; // Delay before airdrop kicks in. UINT8 curshield; // see kartshields_t UINT8 bubblecool; // Bubble Shield use cooldown diff --git a/src/deh_soc.c b/src/deh_soc.c index e75221663..0e0101559 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -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 }, { "DUMMYSTAFF", &cv_dummystaff }, { "DUMMYMULTIPLAYER", &cv_dummymultiplayer }, { "DUMMYIP", &cv_dummyip }, diff --git a/src/doomdef.h b/src/doomdef.h index f1e9a57fd..8355f8528 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -103,7 +103,7 @@ extern "C" { // Special Hashing. //#define NOFILEHASH -//#define NOVERIFYIWADS +#define NOVERIFYIWADS // Uncheck this to compile debugging code //#define RANGECHECK diff --git a/src/g_demo.c b/src/g_demo.c index ba55c2863..9e4ddb426 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -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; } else { diff --git a/src/g_demo.h b/src/g_demo.h index 9271d2240..818974bed 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -41,6 +41,7 @@ typedef enum RAF_SLIPDASH = 1<<3, RAF_PURPLEDRIFT = 1<<4, RAF_SLOPEBOOST = 1<<5, + RAF_AIRDROP = 1<<6, // up to 1<<31 is free } raflags_t; diff --git a/src/g_game.c b/src/g_game.c index 56a9c2f1c..3b5d026f1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -483,14 +483,15 @@ SINT8 G_RecordPresetIndex(void) boolean slipdash = cv_dummyattackingslipdash.value; boolean purpledrift = cv_dummyattackingpurpledrift.value; boolean slopeboost = cv_dummyattackingslopeboost.value; + boolean airdrop = cv_dummyattackingairdrop.value; - if (!rings && !stacking && !chaining && !slipdash && !purpledrift && !slopeboost) + if (!rings && !stacking && !chaining && !slipdash && !purpledrift && !slopeboost && !airdrop) return RP_KART; - if (stacking && chaining && slopeboost && !rings && !slipdash && !purpledrift) + if (stacking && chaining && slopeboost && airdrop && !rings && !slipdash && !purpledrift) return RP_TECH; - if (rings && stacking && chaining && slipdash && purpledrift && slopeboost) + if (rings && stacking && chaining && slipdash && purpledrift && slopeboost && airdrop) return RP_BLAN; return RP_CUST; diff --git a/src/k_hud.c b/src/k_hud.c index a31b2238a..0a35d58fa 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -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 11 +#define BASEMODS 12 static void K_DrawServerMods(INT32 x, INT32 y) { UINT8 i, j; @@ -2380,6 +2380,7 @@ 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 Spring", 0, &cv_kartbumpspring, -1, true}, {"Alt. Invin.", 0, NULL, K_GetKartInvinType() == KARTINVIN_ALTERN, true} diff --git a/src/k_kart.c b/src/k_kart.c index 7a9697293..46b4b8296 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6592,11 +6592,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); @@ -6633,6 +6629,93 @@ 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 + && !P_IsObjectOnGround(player->mo) + && !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; + } + } + 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; + } + + K_SpawnFallLines(player, player->rings > 0); + player->mo->momz -= FixedMul(gravity, mapobjectscale)*P_MobjFlip(player->mo); + } + + if (player->airdroptime < UINT8_MAX) + player->airdroptime++; + } + else + { + player->airdroptime = 0; + } +} + /** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c \param player player object passed from P_PlayerThink @@ -6859,6 +6942,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; @@ -9832,7 +9928,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; @@ -10956,6 +11053,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; diff --git a/src/k_kart.h b/src/k_kart.h index c96fada84..b7db43748 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -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); boolean K_BoostChain(player_t *player, INT32 timer, boolean chainsound); INT32 K_ChainOrDeincrementTime(player_t *player, INT32 timer, INT32 deincrement, boolean chainsound); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 8d9b23125..c98d3582f 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4167,6 +4167,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) { @@ -5263,6 +5270,7 @@ static luaL_Reg lib[] = { {"K_SlipdashActive",lib_kSlipdashActive}, {"K_SlopeBoostActive",lib_kSlopeBoostActive}, {"K_DraftingActive",lib_kDraftingActive}, + {"K_AirDropActive",lib_kAirDropActive}, {"K_GetKartInvinType",lib_kGetKartInvinType}, {"K_UsingLegacyCheckpoints",lib_kUsingLegacyCheckpoints}, {"K_DoBoost",lib_kDoBoost}, diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index ee90e99b0..54f15264b 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -256,12 +256,14 @@ 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_curshield, player_bubblecool, player_bubbleblowup, @@ -453,12 +455,14 @@ static const char *const player_opt[] = { "ringmax", "pickuprings", "ringdelay", + "ringlock", "ringboost", "ringtime", "superring", "nextringaward", "ringvolume", "ringtransparency", + "airdroptime", "curshield", "bubblecool", "bubbleblowup", @@ -854,6 +858,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 +879,9 @@ 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_curshield: lua_pushinteger(L, plr->curshield); break; @@ -1534,6 +1544,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 +1565,9 @@ 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_curshield: plr->curshield = luaL_checkinteger(L, 3); break; diff --git a/src/lua_script.c b/src/lua_script.c index f646db2ac..6a2fb7f13 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -397,6 +397,9 @@ 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); + return 1; } else if (fastcmp(word,"purpledriftactive")) { lua_pushinteger(L, purpledriftactive); return 1; diff --git a/src/m_menu.c b/src/m_menu.c index 17558333c..10730ac67 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -455,6 +455,8 @@ 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 dummygpdifficulty_cons_t[] = {{KARTSPEED_EASY, "Easy"}, {KARTSPEED_NORMAL, "Normal"}, {KARTSPEED_HARD, "Hard"}, {KARTSPEED_EXPERT, "Expert"}, {KARTGP_MASTER, "Master"}, {KARTGP_NIGHTMARE, "Nightmare"}, {0, NULL}}; static CV_PossibleValue_t dummygpcup_cons_t[50] = {{1, "TEMP"}}; // A REALLY BIG NUMBER, SINCE THIS IS TEMP UNTIL NEW MENUS @@ -649,6 +651,7 @@ char *M_AppendGametypeAndModName(void) ADD(cv_dummyattackingslipdash, "SD-") ADD(cv_dummyattackingpurpledrift, "PD-") ADD(cv_dummyattackingslopeboost, "SB-") + ADD(cv_dummyattackingairdrop, "AD-") new_str[len-1] = '\0'; @@ -2159,6 +2162,7 @@ void M_Init(void) CV_RegisterVar(&cv_dummyattackingslipdash); CV_RegisterVar(&cv_dummyattackingpurpledrift); CV_RegisterVar(&cv_dummyattackingslopeboost); + CV_RegisterVar(&cv_dummyattackingairdrop); CV_RegisterVar(&cv_dummygpdifficulty); CV_RegisterVar(&cv_dummygpencore); @@ -5851,11 +5855,11 @@ INT32 MR_ReplayStaff(INT32 choice) } #define NUMPRESETS 3 -static boolean presets[NUMPRESETS][6] = { - //rings stacking chaining slipdash purpledrift slopeboost - { false, false, false, false, false, false}, // SRB2Kart - { false, true, true, false, false, true}, // Tech - { true, true, true, true, true, true}, // BlanKart +static boolean presets[NUMPRESETS][7] = { + //rings stacking chaining slipdash purpledrift slopeboost airdrop + { false, false, false, false, false, false, false }, // SRB2Kart + { false, true, true, false, false, true, true }, // Tech + { true, true, true, true, true, true, true }, // BlanKart }; INT32 MR_TimeAttackPreset(INT32 arg) diff --git a/src/m_menu.h b/src/m_menu.h index 82fc059fe..103a8609c 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -422,6 +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_dummyattackingairdrop; extern consvar_t cv_dummystaff; extern consvar_t cv_dummymultiplayer, cv_dummyip, cv_dummyname, cv_dummyfollower, cv_dummycolor; extern consvar_t cv_dummyserverpage; diff --git a/src/p_enemy.c b/src/p_enemy.c index 82566adf1..ca08878c4 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3170,11 +3170,26 @@ 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; + } + 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 +3214,7 @@ void A_AttractChase(mobj_t *actor) ( actor->target->height + offz )* P_MobjFlip(actor)); actor->extravalue1++; } + } else // Collecting { diff --git a/src/p_mobj.h b/src/p_mobj.h index 81f51cb21..d45c54e0e 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -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 UINT16 bossdisabled; extern boolean stoppedclock; diff --git a/src/p_saveg.c b/src/p_saveg.c index 5e211359b..82811fae4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -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,8 @@ 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].curshield); WRITEUINT8(save->p, players[i].bubblecool); WRITEUINT8(save->p, players[i].bubbleblowup); @@ -680,6 +683,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 +691,8 @@ 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].curshield = READUINT8(save->p); players[i].bubblecool = READUINT8(save->p); players[i].bubbleblowup = READUINT8(save->p); @@ -2095,6 +2101,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 +2417,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 +2705,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 +4008,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 +5315,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); for (i = 0; i < 12; i++) { @@ -5685,6 +5703,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); for (i = 0; i < 12; i++) { diff --git a/src/p_setup.c b/src/p_setup.c index 427a7ab4c..b42fe89ea 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -154,6 +154,7 @@ boolean slipdashactive; boolean purpledriftactive; boolean slopeboostactive; boolean draftingactive; +boolean airdropactive; UINT16 bossdisabled; boolean stoppedclock; boolean levelloading; @@ -8034,6 +8035,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate) purpledriftactive = false; slopeboostactive = false; draftingactive = false; + airdropactive = false; if (cv_kartrings.value) ringsactive = true; @@ -8056,6 +8058,9 @@ static void P_InitLevelSettings(boolean reloadinggamestate) if (cv_kartdrafting.value) draftingactive = true; + if (cv_kartairdrop.value) + airdropactive = false; + invintype = (UINT8)cv_kartinvintype.value; // emerald hunt @@ -8146,6 +8151,8 @@ static void P_InitLevelSettings(boolean reloadinggamestate) purpledriftactive = true; if (raflags & RAF_SLOPEBOOST) slopeboostactive = true; + if (raflags & RAF_AIRDROP) + airdropactive = true; } else { @@ -8155,6 +8162,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate) chainingactive = cv_dummyattackingchaining.value; slipdashactive = cv_dummyattackingslipdash.value; slopeboostactive = cv_dummyattackingslopeboost.value; + airdropactive = cv_dummyattackingairdrop.value; } } else