diff --git a/src/d_player.h b/src/d_player.h index 00bb5d1c5..0d932aab5 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -1053,6 +1053,8 @@ struct player_t fixed_t outrun; // Milky Way road effect + fixed_t transfer; // Tired of Ramp Park fastfalls + uint8_t public_key[PUBKEYLENGTH]; #ifdef HWRENDER diff --git a/src/deh_tables.c b/src/deh_tables.c index 0b2e3a9dc..ab4b0907b 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1772,6 +1772,19 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_WIPEOUTTRAIL10", "S_WIPEOUTTRAIL11", + // "Firework" dust trail + "S_FIREWORKTRAIL", + "S_FIREWORKTRAIL2", + "S_FIREWORKTRAIL3", + "S_FIREWORKTRAIL4", + "S_FIREWORKTRAIL5", + "S_FIREWORKTRAIL6", + "S_FIREWORKTRAIL7", + "S_FIREWORKTRAIL8", + "S_FIREWORKTRAIL9", + "S_FIREWORKTRAIL10", + "S_FIREWORKTRAIL11", + // Rocket sneaker "S_ROCKETSNEAKER_L", "S_ROCKETSNEAKER_R", diff --git a/src/info.c b/src/info.c index 40cc9949f..315f02880 100644 --- a/src/info.c +++ b/src/info.c @@ -2316,6 +2316,18 @@ state_t states[NUMSTATES] = {SPR_WIPD, 8, 1, {NULL}, 0, 0, S_WIPEOUTTRAIL10}, // S_WIPEOUTTRAIL9 {SPR_WIPD, 9, 1, {NULL}, 0, 0, S_WIPEOUTTRAIL11}, // S_WIPEOUTTRAIL10 {SPR_WIPD, 10, 1, {NULL}, 0, 0, S_NULL}, // S_WIPEOUTTRAIL11 + + {SPR_WIPD, 0, 1, {NULL}, 0, 0, S_FIREWORKTRAIL2}, // S_FIREWORKTRAIL + {SPR_WIPD, 1|FF_TRANS10, 1, {NULL}, 0, 0, S_FIREWORKTRAIL3}, // S_FIREWORKTRAIL2 + {SPR_WIPD, 2|FF_TRANS20, 1, {NULL}, 0, 0, S_FIREWORKTRAIL4}, // S_FIREWORKTRAIL3 + {SPR_WIPD, 3|FF_TRANS30, 1, {NULL}, 0, 0, S_FIREWORKTRAIL5}, // S_FIREWORKTRAIL4 + {SPR_WIPD, 4|FF_TRANS40, 1, {NULL}, 0, 0, S_FIREWORKTRAIL6}, // S_FIREWORKTRAIL5 + {SPR_WIPD, 5|FF_TRANS50, 1, {NULL}, 0, 0, S_FIREWORKTRAIL7}, // S_FIREWORKTRAIL6 + {SPR_WIPD, 6|FF_TRANS60, 1, {NULL}, 0, 0, S_FIREWORKTRAIL8}, // S_FIREWORKTRAIL7 + {SPR_WIPD, 7|FF_TRANS70, 1, {NULL}, 0, 0, S_FIREWORKTRAIL9}, // S_FIREWORKTRAIL8 + {SPR_WIPD, 8|FF_TRANS80, 1, {NULL}, 0, 0, S_FIREWORKTRAIL10}, // S_FIREWORKTRAIL9 + {SPR_WIPD, 9|FF_TRANS90, 1, {NULL}, 0, 0, S_FIREWORKTRAIL11}, // S_FIREWORKTRAIL10 + {SPR_WIPD, 10|FF_TRANS90, 1, {NULL}, 0, 0, S_NULL}, // S_FIREWORKTRAIL11 {SPR_RSHE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_L {SPR_RSHE, 1, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_R diff --git a/src/info.h b/src/info.h index e16625725..f8c880633 100644 --- a/src/info.h +++ b/src/info.h @@ -2798,6 +2798,19 @@ typedef enum state S_WIPEOUTTRAIL10, S_WIPEOUTTRAIL11, + // "Firework"" dust trail + S_FIREWORKTRAIL1, + S_FIREWORKTRAIL2, + S_FIREWORKTRAIL3, + S_FIREWORKTRAIL4, + S_FIREWORKTRAIL5, + S_FIREWORKTRAIL6, + S_FIREWORKTRAIL7, + S_FIREWORKTRAIL8, + S_FIREWORKTRAIL9, + S_FIREWORKTRAIL10, + S_FIREWORKTRAIL11, + // Rocket sneaker S_ROCKETSNEAKER_L, S_ROCKETSNEAKER_R, diff --git a/src/k_kart.c b/src/k_kart.c index 6ac5d873c..868655caf 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5096,6 +5096,8 @@ void K_TumbleInterrupt(player_t *player) player->pflags &= ~PF_TUMBLELASTBOUNCE; //players->tumbleHeight = 20; + player->transfer = 0; + player->mo->rollangle = 0; player->spinouttype = KSPIN_WIPEOUT; player->spinouttimer = player->wipeoutslow = TICRATE+2; @@ -6268,6 +6270,33 @@ void K_SpawnWipeoutTrail(mobj_t *mo) K_FlipFromObject(dust, mo); } +void K_SpawnFireworkTrail(mobj_t *mo) +{ + mobj_t *dust; + + I_Assert(mo != NULL); + I_Assert(!P_MobjWasRemoved(mo)); + + dust = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_WIPEOUTTRAIL); + + P_SetTarget(&dust->target, mo); + dust->angle = K_MomentumAngle(mo); + + P_SetMobjState(dust, S_FIREWORKTRAIL1); + + if (mo->player) + dust->color = mo->player->skincolor; + else + dust->color = mo->color; + dust->colorized = true; + + P_InstaScale(dust, mo->scale/2); + dust->destscale = 2*mo->scale; + dust->scalespeed = mo->scale/2; + + K_FlipFromObject(dust, mo); +} + void K_SpawnDraftDust(mobj_t *mo) { UINT8 i; @@ -9014,6 +9043,50 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->itemtype == KITEM_NONE) player->itemflags &= ~IF_HOLDREADY; + if (onground) + player->transfer = 0; + + if (player->transfer) + { + if ((abs(player->mo->momz) < (2*abs(player->transfer)/4)) || (player->mo->momz > 0) != (player->transfer > 0)) + { + fixed_t fuckfactor = FRACUNIT; + fixed_t transfergravity = 10*FRACUNIT/100; + + fixed_t transferclamp = min(abs(player->transfer), (player->mo->scale*100)); + if (player->transfer < 0) + transferclamp *= -1; + + if ((player->mo->momz > 0) == (transferclamp > 0)) + { + if (!S_SoundPlaying(player->mo, sfx_ggfall)) + S_StartSound(player->mo, sfx_ggfall); + + fuckfactor = FRACUNIT/2; + } + + fixed_t sx, sy; + sx = P_RandomRange(PR_DECORATION, -48, 48)*FRACUNIT; + sy = P_RandomRange(PR_DECORATION, -48, 48)*FRACUNIT; + + mobj_t *spdl = P_SpawnMobjFromMobj(player->mo, sx, sy, 0, MT_DOWNLINE); + spdl->colorized = true; + spdl->color = player->skincolor; + K_MatchGenericExtraFlags(spdl, player->mo); + P_SetTarget(&spdl->owner, player->mo); + spdl->renderflags |= RF_REDUCEVFX; + P_InstaScale(spdl, 4*player->mo->scale/2); + + if (abs(player->mo->momz) < (3*transferclamp/2)) + player->mo->momz -= FixedMul(transferclamp, FixedMul(fuckfactor, transfergravity)); + } + else + { + if (leveltime % 2) + K_SpawnFireworkTrail(player->mo); + } + } + // DKR style camera for boosting if (player->karthud[khud_boostcam] != 0 || player->karthud[khud_destboostcam] != 0) { @@ -10099,7 +10172,6 @@ void K_KartResetPlayerColor(player_t *player) fullbright = true; player->mo->color = player->skincolor; goto finalise; - } else if (player->overdrive) { @@ -10109,6 +10181,21 @@ void K_KartResetPlayerColor(player_t *player) goto finalise; } + if (player->transfer && (leveltime & 1)) + { + player->mo->colorized = true; + fullbright = true; + player->mo->color = player->skincolor; + goto finalise; + } + else if (player->transfer) + { + player->mo->colorized = true; + fullbright = true; + player->mo->color = SKINCOLOR_WHITE; + goto finalise; + } + if (player->ringboost && (leveltime & 1)) // ring boosting { player->mo->colorized = true; diff --git a/src/k_kart.h b/src/k_kart.h index bf73ffcf2..81bb5c9a4 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -174,6 +174,7 @@ UINT16 K_DriftSparkColor(player_t *player, INT32 charge); void K_SpawnBoostTrail(player_t *player); void K_SpawnSparkleTrail(mobj_t *mo); void K_SpawnWipeoutTrail(mobj_t *mo); +void K_SpawnFireworkTrail(mobj_t *mo); void K_SpawnDraftDust(mobj_t *mo); void K_SpawnMagicianParticles(mobj_t *mo, int spread); void K_DriftDustHandling(mobj_t *spawner); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 9398ea373..6c585cb12 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -262,6 +262,8 @@ static int player_get(lua_State *L) lua_pushboolean(L, plr->flipDI); else if (fastcmp(field,"analoginput")) lua_pushboolean(L, plr->analoginput); + else if (fastcmp(field,"transfer")) + lua_pushboolean(L, plr->transfer); else if (fastcmp(field,"markedfordeath")) lua_pushboolean(L, plr->markedfordeath); else if (fastcmp(field,"incontrol")) @@ -855,7 +857,9 @@ static int player_set(lua_State *L) else if (fastcmp(field,"ringvisualwarning")) plr->ringvisualwarning = luaL_checkboolean(L, 3); else if (fastcmp(field,"analoginput")) - plr->markedfordeath = luaL_checkboolean(L, 3); + plr->analoginput = luaL_checkboolean(L, 3); + else if (fastcmp(field,"transfer")) + plr->transfer = luaL_checkboolean(L, 3); else if (fastcmp(field,"markedfordeath")) plr->markedfordeath = luaL_checkboolean(L, 3); else if (fastcmp(field,"dotrickfx")) diff --git a/src/objects/dash-rings.c b/src/objects/dash-rings.c index 89fb81a4e..f7a8637be 100644 --- a/src/objects/dash-rings.c +++ b/src/objects/dash-rings.c @@ -188,6 +188,7 @@ static void DashRingLaunch(player_t *player, mobj_t *ring) player->flashing = 0; player->fastfall = 0; K_TumbleInterrupt(player); + player->transfer = 0; switch (ring->extravalue1) { diff --git a/src/p_map.c b/src/p_map.c index e97f7a1ac..3a2494b75 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -456,6 +456,8 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) spring->reactiontime++; } + + object->player->transfer = 0; } P_SetMobjState(spring, raisestate); diff --git a/src/p_mobj.c b/src/p_mobj.c index ab88f215b..89deadbaf 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1791,6 +1791,12 @@ boolean P_XYMovement(mobj_t *mo) if (P_MobjFlip(mo)*(transfermomz - mo->momz) > 2*FRACUNIT) // Do the actual launch! { mo->momz = transfermomz; + if (mo->player) + { + mo->player->transfer = transfermomz; + S_StartSound(mo, sfx_s3k98); + } + mo->standingslope = NULL; mo->terrain = NULL; P_SetPitchRoll(mo, ANGLE_90, diff --git a/src/p_saveg.c b/src/p_saveg.c index a8638d03d..ad99621d4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -655,6 +655,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].itemflags); WRITEFIXED(save->p, players[i].outrun); + WRITEFIXED(save->p, players[i].transfer); WRITEUINT8(save->p, players[i].rideroid); WRITEUINT8(save->p, players[i].rdnodepull); @@ -1279,6 +1280,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].itemflags = READUINT8(save->p); players[i].outrun = READFIXED(save->p); + players[i].transfer = READFIXED(save->p); players[i].rideroid = (boolean)READUINT8(save->p); players[i].rdnodepull = (boolean)READUINT8(save->p); diff --git a/src/sounds.c b/src/sounds.c index 465af1aac..7e5ac1b73 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1537,6 +1537,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"die02", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"die03", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + // Walltransfer + {"ggfall", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + // SRB2kart - Skin sounds {"kwin", false, 64, 96, -1, NULL, 0, SKSKWIN, -1, LUMPERROR, ""}, {"klose", false, 64, 96, -1, NULL, 0, SKSKLOSE, -1, LUMPERROR, ""}, diff --git a/src/sounds.h b/src/sounds.h index 0abcd2110..bed72efa2 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1613,6 +1613,9 @@ typedef enum sfx_die02, sfx_die03, + // Walltransfer fuck + sfx_ggfall, + // And LASTLY, Kart's skin sounds. sfx_kwin, sfx_klose,