diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 68ff0fdf9..881153682 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -13,11 +13,10 @@ set(SRB2_ASSET_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/installer" CACHE STRING "Path to directory that contains all asset files for the installer.") set(SRB2_ASSET_HASHED -"srb2.srb;\ +"srb2.pk3;\ player.dta;\ -rings.dta;\ -zones.dta;\ -patch.dta" +zones.pk3;\ +patch.pk3" CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!" ) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index bce41d4ec..de5b2ea6c 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3360,7 +3360,7 @@ thingtypes height = 32; flags8text = "[8] Move left from spawn"; } - 136 + 138 { title = "Banpyura"; sprite = "CR2BA0"; diff --git a/src/Makefile b/src/Makefile index 3015aa5d6..8e9e1816d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -86,10 +86,7 @@ D_DIR?=../bin/Resources D_FILES=$(D_DIR)/srb2.pk3 \ $(D_DIR)/player.dta \ - $(D_DIR)/rings.wpn \ - $(D_DIR)/drill.dta \ - $(D_DIR)/soar.dta \ - $(D_DIR)/zones.dta \ + $(D_DIR)/zones.pk3 \ $(D_DIR)/music.dta \ PKG_CONFIG?=pkg-config diff --git a/src/config.h.in b/src/config.h.in index fc32aef82..58d07e26d 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -13,7 +13,7 @@ #define ASSET_HASH_SRB2_PK3 "${SRB2_ASSET_srb2.pk3_HASH}" #define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}" -#define ASSET_HASH_ZONES_DTA "${SRB2_ASSET_zones.dta_HASH}" +#define ASSET_HASH_ZONES_PK3 "${SRB2_ASSET_zones.pk3_HASH}" #ifdef USE_PATCH_DTA #define ASSET_HASH_PATCH_PK3 "${SRB2_ASSET_patch.pk3_HASH}" #endif @@ -30,7 +30,7 @@ * Last updated 2018 / ?? / ?? - v2.2 - patch.pk3 */ #define ASSET_HASH_SRB2_PK3 "c1b9577687f8a795104aef4600720ea7" -#define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60" +#define ASSET_HASH_ZONES_PK3 "303838c6c534d9540288360fa49cca60" #define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799" #ifdef USE_PATCH_DTA #define ASSET_HASH_PATCH_PK3 "dbbf8bc6121618ee3be2d5b14650429b" diff --git a/src/d_main.c b/src/d_main.c index e71b1cdb3..52f1d2997 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -852,7 +852,7 @@ static void IdentifyVersion(void) // checking in D_SRB2Main // Add the maps - D_AddFile(va(pandf,srb2waddir,"zones.dta")); + D_AddFile(va(pandf,srb2waddir,"zones.pk3")); // Add the players D_AddFile(va(pandf,srb2waddir, "player.dta")); @@ -1145,10 +1145,10 @@ void D_SRB2Main(void) // Check MD5s of autoloaded files W_VerifyFileMD5(mainwads++, ASSET_HASH_SRB2_PK3); // srb2.pk3 - W_VerifyFileMD5(mainwads++, ASSET_HASH_ZONES_DTA); // zones.dta + W_VerifyFileMD5(mainwads++, ASSET_HASH_ZONES_PK3); // zones.pk3 W_VerifyFileMD5(mainwads++, ASSET_HASH_PLAYER_DTA); // player.dta #ifdef USE_PATCH_DTA - W_VerifyFileMD5(mainwads++, ASSET_HASH_PATCH_DTA); // patch.dta + W_VerifyFileMD5(mainwads++, ASSET_HASH_PATCH_DTA); // patch.pk3 #endif // don't check music.dta because people like to modify it, and it doesn't matter if they do // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for. @@ -1157,7 +1157,7 @@ void D_SRB2Main(void) #else mainwads++; // srb2.pk3 - mainwads++; // zones.dta + mainwads++; // zones.pk3 mainwads++; // player.dta #ifdef USE_PATCH_DTA mainwads++; // patch.dta diff --git a/src/d_netfil.c b/src/d_netfil.c index ed2d11138..5e7f59310 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -752,11 +752,9 @@ void Got_Filetxpak(void) nameonly(filename); if (!(strcmp(filename, "srb2.pk3") - && strcmp(filename, "srb2.srb") - && strcmp(filename, "srb2.wad") - && strcmp(filename, "zones.dta") + && strcmp(filename, "zones.pk3") && strcmp(filename, "player.dta") - && strcmp(filename, "patch.dta") + && strcmp(filename, "patch.pk3") && strcmp(filename, "music.dta") )) I_Error("Tried to download \"%s\"", filename); diff --git a/src/d_player.h b/src/d_player.h index 90098917f..f2fdda050 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -513,6 +513,10 @@ typedef struct player_s #endif } player_t; +// Values for dashmode +#define DASHMODE_THRESHOLD (3*TICRATE) +#define DASHMODE_MAX (DASHMODE_THRESHOLD + 3) + // Value for infinite lives #define INFLIVES 0x7F diff --git a/src/dehacked.c b/src/dehacked.c index 33d808ace..df2295216 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4360,6 +4360,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // CA_GLIDEANDCLIMB "S_PLAY_GLIDE", + "S_PLAY_GLIDE_LANDING", "S_PLAY_CLING", "S_PLAY_CLIMB", @@ -4459,6 +4460,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TAILSOVERLAY_GASP", "S_TAILSOVERLAY_EDGE", + // [: + "S_JETFUMEFLASH", + // Blue Crawla "S_POSS_STND", "S_POSS_RUN1", @@ -7495,6 +7499,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_THOK", // Thok! mobj "MT_PLAYER", "MT_TAILSOVERLAY", // c: + "MT_METALJETFUME", // [: // Enemies "MT_BLUECRAWLA", // Crawla (Blue) @@ -9293,6 +9298,7 @@ struct { {"TC_ALLWHITE",TC_ALLWHITE}, {"TC_RAINBOW",TC_RAINBOW}, {"TC_BLINK",TC_BLINK}, + {"TC_DASHMODE",TC_DASHMODE}, #endif {NULL,0} diff --git a/src/g_game.c b/src/g_game.c index 1c6efe45e..e2f43e4f2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -968,8 +968,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) forcefullinput = true; if (twodlevel || (player->mo && (player->mo->flags2 & MF2_TWOD)) - || (!demoplayback && (player->climbing - || (player->powers[pw_carry] == CR_NIGHTSMODE) + || (!demoplayback && ((player->powers[pw_carry] == CR_NIGHTSMODE) || (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))))) // Analog forcestrafe = true; if (forcestrafe) @@ -1150,8 +1149,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (!mouseaiming && cv_mousemove.value) forward += mousey; - if ((!demoplayback && (player->climbing - || (player->pflags & PF_SLIDING)))) // Analog for mouse + if ((!demoplayback && (player->pflags & PF_SLIDING))) // Analog for mouse side += mousex*2; else if (cv_analog.value) { diff --git a/src/info.c b/src/info.c index 6ee3eea15..cfaad552d 100644 --- a/src/info.c +++ b/src/info.c @@ -533,6 +533,7 @@ char spr2names[NUMPLAYERSPRITES][5] = "TIRE", "GLID", + "LAND", "CLNG", "CLMB", @@ -540,7 +541,6 @@ char spr2names[NUMPLAYERSPRITES][5] = "FRUN", "BNCE", - "BLND", "FIRE", @@ -636,6 +636,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = { 0, // SPR2_TIRE, (conditional, will never be referenced) SPR2_FLY , // SPR2_GLID, + SPR2_ROLL, // SPR2_LAND, SPR2_CLMB, // SPR2_CLNG, SPR2_ROLL, // SPR2_CLMB, @@ -643,7 +644,6 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = { SPR2_RUN , // SPR2_FRUN, SPR2_FALL, // SPR2_BNCE, - SPR2_ROLL, // SPR2_BLND, 0, // SPR2_FIRE, @@ -766,6 +766,7 @@ state_t states[NUMSTATES] = // CA_GLIDEANDCLIMB {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE + {SPR_PLAY, SPR2_LAND, 9, {NULL}, 0, 0, S_PLAY_STND}, // S_PLAY_GLIDE_LANDING {SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB @@ -775,7 +776,7 @@ state_t states[NUMSTATES] = // CA_BOUNCE {SPR_PLAY, SPR2_BNCE|FF_ANIMATE, -1, {NULL}, 0, 0, S_NULL}, // S_PLAY_BOUNCE - {SPR_PLAY, SPR2_BLND|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_BOUNCE, 0, S_PLAY_BOUNCE_LANDING}, // S_PLAY_BOUNCE_LANDING + {SPR_PLAY, SPR2_LAND|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_BOUNCE, 0, S_PLAY_BOUNCE_LANDING}, // S_PLAY_BOUNCE_LANDING // CA2_GUNSLINGER {SPR_PLAY, SPR2_FIRE|FF_SPR2ENDSTATE, 2, {NULL}, S_PLAY_FIRE_FINISH, 0, S_PLAY_FIRE}, // S_PLAY_FIRE @@ -866,6 +867,9 @@ state_t states[NUMSTATES] = {SPR_PLAY, SPR2_TALA|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_GASP}, // S_TAILSOVERLAY_GASP {SPR_PLAY, SPR2_TALB , 35, {NULL}, 0, 0, S_TAILSOVERLAY_EDGE}, // S_TAILSOVERLAY_EDGE + // [: + {SPR_JETF, 3|FF_ANIMATE|FF_FULLBRIGHT, 2, {NULL}, 1, 1, S_JETFUME1}, // S_JETFUMEFLASH + // Blue Crawla {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND {SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1 @@ -4133,6 +4137,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_METALJETFUME + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_JETFUMEFLASH, // 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 + 8, // speed + 8*FRACUNIT, // radius + 16*FRACUNIT, // height + 2, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_JETFUME1 // raisestate + }, + { // MT_BLUECRAWLA 100, // doomednum S_POSS_STND, // spawnstate diff --git a/src/info.h b/src/info.h index 95e423dcc..e7f41f585 100644 --- a/src/info.h +++ b/src/info.h @@ -796,6 +796,7 @@ typedef enum playersprite SPR2_TIRE, // tired SPR2_GLID, // glide + SPR2_LAND, // landing after glide/bounce SPR2_CLNG, // cling SPR2_CLMB, // climb @@ -803,7 +804,6 @@ typedef enum playersprite SPR2_FRUN, // float run SPR2_BNCE, // bounce - SPR2_BLND, // bounce landing SPR2_FIRE, // fire @@ -931,6 +931,7 @@ typedef enum state // CA_GLIDEANDCLIMB S_PLAY_GLIDE, + S_PLAY_GLIDE_LANDING, S_PLAY_CLING, S_PLAY_CLIMB, @@ -1030,6 +1031,9 @@ typedef enum state S_TAILSOVERLAY_GASP, S_TAILSOVERLAY_EDGE, + // [: + S_JETFUMEFLASH, + // Blue Crawla S_POSS_STND, S_POSS_RUN1, @@ -4089,6 +4093,7 @@ typedef enum mobj_type MT_THOK, // Thok! mobj MT_PLAYER, MT_TAILSOVERLAY, // c: + MT_METALJETFUME, // Enemies MT_BLUECRAWLA, // Crawla (Blue) diff --git a/src/m_menu.c b/src/m_menu.c index 3b37769eb..17461c5ff 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -400,7 +400,8 @@ consvar_t cv_showfocuslost = {"showfocuslost", "Yes", CV_SAVE, CV_YesNo, NULL, 0 static CV_PossibleValue_t map_cons_t[] = { {1,"MIN"}, - {NUMMAPS, "MAX"} + {NUMMAPS, "MAX"}, + {0,NULL} }; consvar_t cv_nextmap = {"nextmap", "1", CV_HIDEN|CV_CALL, map_cons_t, Nextmap_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -10576,7 +10577,7 @@ static void M_DrawJoystick(void) compareval = cv_usejoystick.value; #else compareval2 = cv_usejoystick2.value; - compareval = cv_usejoystick.value + compareval = cv_usejoystick.value; #endif if ((setupcontrols_secondaryplayer && (i == compareval2)) diff --git a/src/p_inter.c b/src/p_inter.c index 53e1899e1..9017f795d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -477,6 +477,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momy = -toucher->momy; if (player->charability == CA_FLY && player->panim == PA_ABILITY) toucher->momz = -toucher->momz/2; + else if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) + { + player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); + P_SetPlayerMobjState(toucher, S_PLAY_FALL); + toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); + toucher->momx = 7*toucher->momx>>3; + toucher->momy = 7*toucher->momy>>3; + } + else if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) + && player->panim == PA_DASH) + P_DoPlayerPain(player, special, special); } P_DamageMobj(special, toucher, toucher, 1, 0); if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) @@ -1518,10 +1529,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momx = P_ReturnThrustX(special, angle, touchspeed); toucher->momy = P_ReturnThrustY(special, angle, touchspeed); toucher->momz = -toucher->momz; - if (player->pflags & PF_GLIDING) + if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) { player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); P_SetPlayerMobjState(toucher, S_PLAY_FALL); + toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); + toucher->momx = 7*toucher->momx>>3; + toucher->momy = 7*toucher->momy>>3; } player->homing = 0; @@ -1566,10 +1580,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momx = P_ReturnThrustX(special, special->angle, touchspeed); toucher->momy = P_ReturnThrustY(special, special->angle, touchspeed); toucher->momz = -toucher->momz; - if (player->pflags & PF_GLIDING) + if (player->pflags & PF_GLIDING && !P_IsObjectOnGround(toucher)) { player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); P_SetPlayerMobjState(toucher, S_PLAY_FALL); + toucher->momz += P_MobjFlip(toucher) * (player->speed >> 3); + toucher->momx = 7*toucher->momx>>3; + toucher->momy = 7*toucher->momy>>3; } player->homing = 0; diff --git a/src/p_map.c b/src/p_map.c index 7267d65ba..159489f70 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3484,13 +3484,13 @@ isblocking: && canclimb) { slidemo->angle = climbangle; - if (!demoplayback || P_AnalogMove(slidemo->player)) + /*if (!demoplayback || P_AnalogMove(slidemo->player)) { if (slidemo->player == &players[consoleplayer]) localangle = slidemo->angle; else if (slidemo->player == &players[secondarydisplayplayer]) localangle2 = slidemo->angle; - } + }*/ if (!slidemo->player->climbing) { diff --git a/src/p_mobj.c b/src/p_mobj.c index e071f79d8..5735dc27b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7976,7 +7976,7 @@ void P_MobjThinker(mobj_t *mobj) INT32 strength; ++mobj->movedir; mobj->frame &= ~FF_TRANSMASK; - strength = min(mobj->fuse, mobj->movedir)*3; + strength = min(mobj->fuse, (INT32)mobj->movedir)*3; if (strength < 10) mobj->frame |= ((10-strength)<<(FF_TRANSSHIFT)); } diff --git a/src/p_user.c b/src/p_user.c index 14efcd4a6..f81f6d956 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1096,6 +1096,9 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) // Spinning. if (player->pflags & PF_SPINNING) return true; + + if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) + return true; // From the front. if (((player->pflags & PF_GLIDING) || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) @@ -1990,7 +1993,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj); P_SetTarget(&ghost2->tracer, ghost); P_SetTarget(&ghost->tracer, ghost2); - ghost2->flags2 |= MF2_LINKDRAW; + ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); } return ghost; @@ -2260,6 +2263,18 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) else if (!player->skidtime) player->pflags &= ~PF_GLIDING; } + else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && (~player->pflags) & PF_SHIELDABILITY) + { + if (player->mo->state-states != S_PLAY_GLIDE_LANDING) + { + P_ResetPlayer(player); + P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING); + S_StartSound(player->mo, sfx_s3k4c); + player->pflags |= PF_STASIS; + player->mo->momx = ((player->mo->momx - player->cmomx)/3) + player->cmomx; + player->mo->momy = ((player->mo->momy - player->cmomy)/3) + player->cmomy; + } + } else if (player->charability2 == CA2_MELEE && ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY && player->cmd.buttons & (BT_JUMP|BT_USE)))) { @@ -2313,7 +2328,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) { if (player->cmomx || player->cmomy) { - if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) + if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH) P_SetPlayerMobjState(player->mo, S_PLAY_DASH); else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) @@ -2326,7 +2341,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) } else { - if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim != PA_DASH) + if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH) P_SetPlayerMobjState(player->mo, S_PLAY_DASH); else if (player->speed >= FixedMul(player->runspeed, player->mo->scale) && (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN)) @@ -2487,7 +2502,7 @@ static void P_CheckBustableBlocks(player_t *player) // or you are recording for Metal Sonic if (!((player->pflags & PF_SPINNING) && !(player->pflags & PF_JUMPED)) && !(player->powers[pw_super]) - && !((player->charflags & SF_DASHMODE) && (player->dashmode >= 3*TICRATE)) + && !(((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) && (player->dashmode >= DASHMODE_THRESHOLD)) && !(player->pflags & PF_DRILLING) && !metalrecording) continue; @@ -3077,7 +3092,6 @@ static void P_DoClimbing(player_t *player) glidesector = R_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy); - if (!glidesector || glidesector->sector != player->mo->subsector->sector) { boolean floorclimb = false; boolean thrust = false; @@ -3461,9 +3475,13 @@ static void P_DoClimbing(player_t *player) if (!floorclimb) { if (boostup) + { P_SetObjectMomZ(player->mo, 2*FRACUNIT, true); + if (cmd->forwardmove) + P_SetObjectMomZ(player->mo, 2*player->mo->momz/3, false); + } if (thrust) - P_InstaThrust(player->mo, player->mo->angle, FixedMul(4*FRACUNIT, player->mo->scale)); // Lil' boost up. + P_Thrust(player->mo, player->mo->angle, FixedMul(4*FRACUNIT, player->mo->scale)); // Lil' boost up. player->climbing = 0; player->pflags |= P_GetJumpFlags(player); @@ -3477,12 +3495,6 @@ static void P_DoClimbing(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } } - else - { - player->climbing = 0; - player->pflags |= P_GetJumpFlags(player); - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); - } if (cmd->sidemove != 0 || cmd->forwardmove != 0) climb = true; @@ -3501,15 +3513,28 @@ static void P_DoClimbing(player_t *player) player->pflags |= P_GetJumpFlags(player); P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); P_SetObjectMomZ(player->mo, 4*FRACUNIT, false); - P_InstaThrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale)); + P_Thrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale)); } +#define CLIMBCONEMAX FixedAngle(90*FRACUNIT) if (!demoplayback || P_AnalogMove(player)) { if (player == &players[consoleplayer]) - localangle = player->mo->angle; + { + angle_t angdiff = localangle - player->mo->angle; + if (angdiff < ANGLE_180 && angdiff > CLIMBCONEMAX) + localangle = player->mo->angle + CLIMBCONEMAX; + else if (angdiff > ANGLE_180 && angdiff < InvAngle(CLIMBCONEMAX)) + localangle = player->mo->angle - CLIMBCONEMAX; + } else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + { + angle_t angdiff = localangle2 - player->mo->angle; + if (angdiff < ANGLE_180 && angdiff > CLIMBCONEMAX) + localangle2 = player->mo->angle + CLIMBCONEMAX; + else if (angdiff > ANGLE_180 && angdiff < InvAngle(CLIMBCONEMAX)) + localangle2 = player->mo->angle - CLIMBCONEMAX; + } } if (player->climbing == 0) @@ -4497,7 +4522,8 @@ static void P_DoSpinDashDust(player_t *player) static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { boolean canstand = true; // can we stand on the ground? (mostly relevant for slopes) - if (player->pflags & PF_STASIS) + if (player->pflags & PF_STASIS + && (player->pflags & PF_JUMPSTASIS || player->mo->state-states != S_PLAY_GLIDE_LANDING)) return; #ifdef HAVE_BLUA @@ -4521,7 +4547,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { case CA2_SPINDASH: // Spinning and Spindashing // Start revving - if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<mo->scale) + if ((cmd->buttons & BT_USE) && (player->speed < FixedMul(5<mo->scale) || player->mo->state - states == S_PLAY_GLIDE_LANDING) && !player->mo->momz && onground && !(player->pflags & (PF_USEDOWN|PF_SPINNING)) && canstand) { @@ -5283,7 +5309,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->glidetime = 0; P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); - P_InstaThrust(player->mo, player->mo->angle, FixedMul(glidespeed, player->mo->scale)); + if (player->speed < glidespeed) + P_Thrust(player->mo, player->mo->angle, glidespeed - player->speed); player->pflags &= ~(PF_SPINNING|PF_STARTDASH); } break; @@ -5300,7 +5327,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) case CA_SLOWFALL: // Slow descent hover if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) { - if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE) + if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD) P_SetPlayerMobjState(player->mo, S_PLAY_DASH); else if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); @@ -5726,7 +5753,7 @@ static void P_2dMovement(player_t *player) if (player->climbing) { if (cmd->forwardmove != 0) - P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT,10*FRACUNIT), false); + P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false); player->mo->momx = 0; } @@ -5943,7 +5970,7 @@ static void P_3dMovement(player_t *player) if (player->climbing) { if (cmd->forwardmove) - P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false); + P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false); } else if (!analogmove && cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting @@ -5977,7 +6004,7 @@ static void P_3dMovement(player_t *player) } // Sideways movement if (player->climbing) - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale)); + P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1)); // Analog movement control else if (analogmove) { @@ -7676,15 +7703,17 @@ static void P_SkidStuff(player_t *player) { player->skidtime = 0; player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); + player->pflags |= PF_THOKKED; // nice try, speedrunners (but for real this is just behavior from S3K) P_SetPlayerMobjState(player->mo, S_PLAY_FALL); } // Get up and brush yourself off, idiot. - else if (player->glidetime > 15) + else if (player->glidetime > 15 || !(player->cmd.buttons & BT_JUMP)) { P_ResetPlayer(player); - P_SetPlayerMobjState(player->mo, S_PLAY_STND); - player->mo->momx = player->cmomx; - player->mo->momy = player->cmomy; + P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING); + player->pflags |= PF_STASIS; + player->mo->momx = ((player->mo->momx - player->cmomx)/3) + player->cmomx; + player->mo->momy = ((player->mo->momy - player->cmomy)/3) + player->cmomy; } // Didn't stop yet? Skid FOREVER! else if (player->skidtime == 1) @@ -7692,7 +7721,8 @@ static void P_SkidStuff(player_t *player) // Spawn a particle every 3 tics. else if (!(player->skidtime % 3)) { - mobj_t *particle = P_SpawnMobjFromMobj(player->mo, P_RandomRange(-player->mo->radius, player->mo->radius), P_RandomRange(-player->mo->radius, player->mo->radius), 0, MT_SPINDUST); + fixed_t radius = player->mo->radius >> FRACBITS; + mobj_t *particle = P_SpawnMobjFromMobj(player->mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST); particle->tics = 10; particle->destscale = (2*player->mo->scale)/3; @@ -7790,6 +7820,12 @@ static void P_MovePlayer(player_t *player) if (!(player->powers[pw_nocontrol] & (1<<15))) player->pflags |= PF_JUMPSTASIS; } + + if (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) + { + player->pflags |= PF_STASIS; + } + // note: don't unset stasis here if (!player->spectator && G_TagGametype()) @@ -7945,7 +7981,7 @@ static void P_MovePlayer(player_t *player) if ((cmd->forwardmove != 0 || cmd->sidemove != 0) || (player->powers[pw_super] && !onground)) { // If the player is in dashmode, here's their peelout. - if (player->charflags & SF_DASHMODE && player->dashmode >= 3*TICRATE && player->panim == PA_RUN && !player->skidtime && (onground || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) + if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim == PA_RUN && !player->skidtime && (onground || ((player->charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super])) P_SetPlayerMobjState (player->mo, S_PLAY_DASH); // If the player is moving fast enough, // break into a run! @@ -7969,7 +8005,7 @@ static void P_MovePlayer(player_t *player) // If your peelout animation is playing, and you're // going too slow, switch back to the run. - if (player->charflags & SF_DASHMODE && player->panim == PA_DASH && player->dashmode < 3*TICRATE) + if (player->charflags & SF_DASHMODE && player->panim == PA_DASH && player->dashmode < DASHMODE_THRESHOLD) P_SetPlayerMobjState(player->mo, S_PLAY_RUN); // If your running animation is playing, and you're @@ -8049,10 +8085,13 @@ static void P_MovePlayer(player_t *player) // AKA my own gravity. =) if (player->pflags & PF_GLIDING) { + mobj_t *mo = player->mo; // seriously why isn't this at the top of the function hngngngng fixed_t leeway; fixed_t glidespeed = player->actionspd; + fixed_t momx = mo->momx - player->cmomx, momy = mo->momy - player->cmomy; + angle_t angle, moveangle = R_PointToAngle2(0, 0, momx, momy); - if (player->powers[pw_super]) + if (player->powers[pw_super] || player->powers[pw_sneakers]) glidespeed *= 2; if (player->mo->eflags & MFE_VERTICALFLIP) @@ -8067,22 +8106,46 @@ static void P_MovePlayer(player_t *player) } // Strafing while gliding. - leeway = FixedAngle(cmd->sidemove*(FRACUNIT/2)); + leeway = FixedAngle(cmd->sidemove*(FRACUNIT)); + angle = mo->angle - leeway; - if (player->skidtime) // ground gliding + if (!player->skidtime) // TODO: make sure this works in 2D! { - fixed_t speed = FixedMul(glidespeed, FRACUNIT - (FRACUNIT>>2)); - if (player->mo->eflags & MFE_UNDERWATER) - speed >>= 1; - speed = FixedMul(speed - player->glidetime*FRACUNIT, player->mo->scale); - if (speed < 0) - speed = 0; - P_InstaThrust(player->mo, player->mo->angle-leeway, speed); + fixed_t speed, scale = mo->scale; + fixed_t newMagnitude, oldMagnitude = R_PointToDist2(momx, momy, 0, 0); + fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE(((angle-moveangle) >> ANGLETOFINESHIFT) & FINEMASK); // mamgic number BAD but this feels right + + if (mo->eflags & MFE_UNDERWATER) + speed = FixedMul((glidespeed>>1) + player->glidetime*750, scale); + else + speed = FixedMul(glidespeed + player->glidetime*1500, scale); + + P_Thrust(mo, angle, FixedMul(accelfactor, scale)); + + newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); + if (newMagnitude > speed) + { + fixed_t tempmomx, tempmomy; + if (oldMagnitude > speed) + { + if (newMagnitude > oldMagnitude) + { + tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), oldMagnitude); + tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), oldMagnitude); + player->mo->momx = tempmomx + player->cmomx; + player->mo->momy = tempmomy + player->cmomy; + } + // else do nothing + } + else + { + tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), speed); + tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), speed); + player->mo->momx = tempmomx + player->cmomx; + player->mo->momy = tempmomy + player->cmomy; + } + } } - else if (player->mo->eflags & MFE_UNDERWATER) - P_InstaThrust(player->mo, player->mo->angle-leeway, FixedMul((glidespeed>>1) + player->glidetime*750, player->mo->scale)); - else - P_InstaThrust(player->mo, player->mo->angle-leeway, FixedMul(glidespeed + player->glidetime*1500, player->mo->scale)); player->glidetime++; @@ -8107,18 +8170,9 @@ static void P_MovePlayer(player_t *player) } else if (player->climbing) // 'Deceleration' for climbing on walls. { - if (player->mo->momz > 0) - { - player->mo->momz -= FixedMul(FRACUNIT/2, player->mo->scale); - if (player->mo->momz < 0) - player->mo->momz = 0; - } - else if (player->mo->momz < 0) - { - player->mo->momz += FixedMul(FRACUNIT/2, player->mo->scale); - if (player->mo->momz > 0) - player->mo->momz = 0; - } + + if (!player->cmd.forwardmove) + player->mo->momz = 0; } else if (player->pflags & PF_BOUNCING) { @@ -10896,6 +10950,123 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails) P_SetThingPosition(tails); } +// Metal Sonic's jet fume +static void P_DoMetalJetFume(player_t *player, mobj_t *fume) +{ + static const UINT8 FUME_SKINCOLORS[] = + { + SKINCOLOR_ICY, + SKINCOLOR_SKY, + SKINCOLOR_CYAN, + SKINCOLOR_WAVE, + SKINCOLOR_TEAL, + SKINCOLOR_AQUA, + SKINCOLOR_SEAFOAM, + SKINCOLOR_MINT, + SKINCOLOR_PERIDOT, + SKINCOLOR_LIME, + SKINCOLOR_YELLOW, + SKINCOLOR_SANDY, + SKINCOLOR_GOLD, + SKINCOLOR_APRICOT, + SKINCOLOR_SUNSET + }; + mobj_t *mo = player->mo; + angle_t angle = player->drawangle; + fixed_t dist; + panim_t panim = player->panim; + tic_t dashmode = player->dashmode; + boolean underwater = mo->eflags & MFE_UNDERWATER; + statenum_t stat = fume->state-states; + + if (panim != PA_WALK && panim != PA_RUN && panim != PA_DASH) // turn invisible when not in a coherent movement state + { + if (stat != fume->info->spawnstate) + P_SetMobjState(fume, fume->info->spawnstate); + return; + } + + if (underwater) // No fume underwater; spawn bubbles instead! + { + fume->movedir += FixedAngle(FixedDiv(2 * player->speed, 3 * mo->scale)); + fume->movefactor += player->speed; + + if (fume->movefactor > FixedDiv(2 * player->normalspeed, 3 * mo->scale)) + { + INT16 i; + fixed_t radiusV = 4*FRACUNIT; + fixed_t radiusX = P_ReturnThrustX(mo, angle, -mo->radius >> (panim == PA_WALK ? 1 : 0)); + fixed_t radiusY = P_ReturnThrustY(mo, angle, -mo->radius >> (panim == PA_WALK ? 1 : 0)); + fixed_t factorX = P_ReturnThrustX(mo, angle + ANGLE_90, mo->scale); + fixed_t factorY = P_ReturnThrustY(mo, angle + ANGLE_90, mo->scale); + fixed_t offsetH, offsetV, x, y, z; + + for (i = -1; i < 2; i += 2) + { + offsetH = i*P_ReturnThrustX(fume, fume->movedir, radiusV); + offsetV = i*P_ReturnThrustY(fume, fume->movedir, radiusV); + x = mo->x + radiusX + FixedMul(offsetH, factorX); + y = mo->y + radiusY + FixedMul(offsetH, factorY); + z = mo->z + (mo->height >> 1) + offsetV; + P_SpawnMobj(x, y, z, MT_SMALLBUBBLE)->scale = mo->scale >> 1; + } + + fume->movefactor = 0; + } + + if (panim == PA_WALK) + { + if (stat != fume->info->spawnstate) + P_SetMobjState(fume, fume->info->spawnstate); + return; + } + } + + if (stat == fume->info->spawnstate) // If currently inivisble, activate! + { + P_SetMobjState(fume, (stat = fume->info->seestate)); + P_SetScale(fume, mo->scale); + } + + if (dashmode > DASHMODE_THRESHOLD && stat != fume->info->seestate) // If in dashmode, grow really big and flash + { + fume->destscale = mo->scale; + fume->flags2 ^= MF2_DONTDRAW; + fume->flags2 |= mo->flags2 & MF2_DONTDRAW; + } + else // Otherwise, pick a size and color depending on speed and proximity to dashmode + { + if (dashmode == DASHMODE_THRESHOLD && dashmode > (tic_t)fume->movecount) // If just about to enter dashmode, play the startup animation again + { + P_SetMobjState(fume, (stat = fume->info->seestate)); + P_SetScale(fume, mo->scale << 1); + } + fume->flags2 = (fume->flags2 & ~MF2_DONTDRAW) | (mo->flags2 & MF2_DONTDRAW); + fume->destscale = (mo->scale + FixedDiv(player->speed, player->normalspeed)) / (underwater ? 6 : 3); + fume->color = FUME_SKINCOLORS[(dashmode * sizeof(FUME_SKINCOLORS)) / (DASHMODE_MAX + 1)]; + + if (underwater) + { + fume->frame = (fume->frame & FF_FRAMEMASK) | FF_ANIMATE | (P_RandomRange(0, 9) * FF_TRANS10); + } + } + + fume->movecount = dashmode; // keeps track of previous dashmode value so we know whether Metal is entering or leaving it + fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP); // Make sure to flip in reverse gravity! + + // Finally, set its position + dist = -mo->radius - FixedMul(fume->info->radius, fume->destscale - mo->scale/3); + + P_UnsetThingPosition(fume); + fume->x = mo->x + P_ReturnThrustX(fume, angle, dist); + fume->y = mo->y + P_ReturnThrustY(fume, angle, dist); + if (fume->eflags & MFE_VERTICALFLIP) + fume->z = mo->z + ((mo->height + fume->height) >> 1); + else + fume->z = mo->z + ((mo->height - fume->height) >> 1); + P_SetThingPosition(fume); +} + // // P_PlayerThink // @@ -11292,8 +11463,7 @@ void P_PlayerThink(player_t *player) || player->powers[pw_carry] == CR_NIGHTSMODE) ; else if (!(player->pflags & PF_DIRECTIONCHAR) - || (player->climbing // stuff where the direction is forced at all times - || (player->pflags & PF_GLIDING)) + || (player->climbing) // stuff where the direction is forced at all times || (P_AnalogMove(player) || twodlevel || player->mo->flags2 & MF2_TWOD) // keep things synchronised up there, since the camera IS seperate from player motion when that happens || G_RingSlingerGametype()) // no firing rings in directions your player isn't aiming player->drawangle = player->mo->angle; @@ -11349,7 +11519,15 @@ void P_PlayerThink(player_t *player) ; else { - if (player->pflags & PF_SLIDING) + if (player->pflags & PF_GLIDING) + { + if (player->speed < player->mo->scale) + diff = player->mo->angle - player->drawangle; + else + diff = (R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - player->drawangle); + factor = 4; + } + else if (player->pflags & PF_SLIDING) { #if 0 // fun hydrocity style horizontal spin if (player->mo->eflags & MFE_TOUCHWATER || player->powers[pw_flashing] > (flashingtics/4)*3) @@ -11530,8 +11708,8 @@ void P_PlayerThink(player_t *player) else player->powers[pw_justsprung] = 0; - if (player->powers[pw_pushing] && player->powers[pw_pushing] < UINT16_MAX) - player->powers[pw_pushing]--; + if (player->powers[pw_noautobrake] && player->powers[pw_noautobrake] < UINT16_MAX) + player->powers[pw_noautobrake]--; if (player->powers[pw_underwater] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER))) { @@ -11641,9 +11819,9 @@ void P_PlayerThink(player_t *player) if ((totallyradical && !floating) || (player->pflags & PF_STARTDASH)) { - if (dashmode < 3*TICRATE + 3) + if (dashmode < DASHMODE_MAX) dashmode++; // Counter. Adds 1 to dash mode per tic in top speed. - if (dashmode == 3*TICRATE) // This isn't in the ">=" equation because it'd cause the sound to play infinitely. + if (dashmode == DASHMODE_THRESHOLD) // This isn't in the ">=" equation because it'd cause the sound to play infinitely. S_StartSound(player->mo, sfx_s3ka2); // If the player enters dashmode, play this sound on the the tic it starts. } else if ((!totallyradical || !floating) && !(player->pflags & PF_SPINNING)) @@ -11654,7 +11832,7 @@ void P_PlayerThink(player_t *player) dashmode = 0; } - if (dashmode < 3*TICRATE) // Exits Dash Mode if you drop below speed/dash counter tics. Not in the above block so it doesn't keep disabling in midair. + if (dashmode < DASHMODE_THRESHOLD) // Exits Dash Mode if you drop below speed/dash counter tics. Not in the above block so it doesn't keep disabling in midair. { player->normalspeed = skins[player->skin].normalspeed; // Reset to default if not capable of entering dash mode. player->jumpfactor = skins[player->skin].jumpfactor; @@ -11676,7 +11854,7 @@ void P_PlayerThink(player_t *player) } else if (dashmode) { - if (dashmode >= 3*TICRATE) // catch getting the flag! + if (dashmode >= DASHMODE_THRESHOLD) // catch getting the flag! { player->normalspeed = skins[player->skin].normalspeed; player->jumpfactor = skins[player->skin].jumpfactor; @@ -12222,7 +12400,15 @@ void P_PlayerAfterThink(player_t *player) { P_SetTarget(&player->followmobj, P_SpawnMobjFromMobj(player->mo, 0, 0, 0, player->followitem)); P_SetTarget(&player->followmobj->tracer, player->mo); - player->followmobj->flags2 |= MF2_LINKDRAW; + switch (player->followmobj->type) + { + case MT_METALJETFUME: + player->followmobj->colorized = true; + break; + default: + player->followmobj->flags2 |= MF2_LINKDRAW; + break; + } } if (player->followmobj) @@ -12238,6 +12424,9 @@ void P_PlayerAfterThink(player_t *player) case MT_TAILSOVERLAY: // c: P_DoTailsOverlay(player, player->followmobj); break; + case MT_METALJETFUME: + P_DoMetalJetFume(player, player->followmobj); + break; default: var1 = 1; var2 = 0; diff --git a/src/r_draw.c b/src/r_draw.c index 1754403c4..bb70a319f 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -130,10 +130,11 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3) #define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4) #define BLINK_TT_CACHE_INDEX (MAXSKINS + 5) +#define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6) #define DEFAULT_STARTTRANSCOLOR 96 #define NUM_PALETTE_ENTRIES 256 -static UINT8** translationtablecache[MAXSKINS + 6] = {NULL}; +static UINT8** translationtablecache[MAXSKINS + 7] = {NULL}; const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = { // {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_NONE @@ -569,6 +570,40 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U dest_colormap[Color_Index[SKINCOLOR_BLUE-1][12-i]] = Color_Index[SKINCOLOR_BLUE-1][i]; dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0; } + else if (skinnum == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices + { + // greens -> ketchups + dest_colormap[96] = dest_colormap[97] = 48; + dest_colormap[98] = 49; + dest_colormap[99] = 51; + dest_colormap[100] = 52; + dest_colormap[101] = dest_colormap[102] = 54; + dest_colormap[103] = 34; + dest_colormap[104] = 37; + dest_colormap[105] = 39; + dest_colormap[106] = 41; + for (i = 0; i < 5; i++) + dest_colormap[107 + i] = 43 + i; + + // reds -> steel blues + dest_colormap[32] = 146; + dest_colormap[33] = 147; + dest_colormap[34] = dest_colormap[35] = 170; + dest_colormap[36] = 171; + dest_colormap[37] = dest_colormap[38] = 172; + dest_colormap[39] = dest_colormap[40] = dest_colormap[41] = 173; + dest_colormap[42] = dest_colormap[43] = dest_colormap[44] = 174; + dest_colormap[45] = dest_colormap[46] = dest_colormap[47] = 175; + dest_colormap[71] = 139; + + // steel blues -> oranges + dest_colormap[170] = 52; + dest_colormap[171] = 54; + dest_colormap[172] = 56; + dest_colormap[173] = 42; + dest_colormap[174] = 45; + dest_colormap[175] = 47; + } return; } else if (color == SKINCOLOR_NONE) @@ -628,6 +663,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags) case TC_ALLWHITE: skintableindex = ALLWHITE_TT_CACHE_INDEX; break; case TC_RAINBOW: skintableindex = RAINBOW_TT_CACHE_INDEX; break; case TC_BLINK: skintableindex = BLINK_TT_CACHE_INDEX; break; + case TC_DASHMODE: skintableindex = DASHMODE_TT_CACHE_INDEX; break; default: skintableindex = skinnum; break; } diff --git a/src/r_draw.h b/src/r_draw.h index 3c1429722..a0ab74848 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -109,6 +109,7 @@ extern lumpnum_t viewborderlump[8]; #define TC_ALLWHITE -4 // For Cy-Brak-demon #define TC_RAINBOW -5 // For single colour #define TC_BLINK -6 // For item blinking, according to kart +#define TC_DASHMODE -7 // For Metal Sonic's dashmode // Initialize color translation tables, for player rendering etc. void R_InitTranslationTables(void); diff --git a/src/r_things.c b/src/r_things.c index 5c99edcec..00eaae1c2 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -753,6 +753,13 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_transmap = vis->transmap; if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized) dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); + else if (!(vis->cut & SC_PRECIP) + && vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD + && (vis->mobj->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) + && ((leveltime/2) & 1)) + { + dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE); + } else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> { size_t skinnum = (skin_t*)vis->mobj->skin-skins; @@ -774,6 +781,13 @@ static void R_DrawVisSprite(vissprite_t *vis) // New colormap stuff for skins Tails 06-07-2002 if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized) dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); + else if (!(vis->cut & SC_PRECIP) + && vis->mobj->player && vis->mobj->player->dashmode >= DASHMODE_THRESHOLD + && (vis->mobj->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) + && ((leveltime/2) & 1)) + { + dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE); + } else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { size_t skinnum = (skin_t*)vis->mobj->skin-skins; diff --git a/src/s_sound.c b/src/s_sound.c index 00576ff55..6134e338c 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -118,8 +118,8 @@ consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL}; // Window focus sound sytem toggles -consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_YesNo}; -consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo}; +consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef HAVE_OPENMPT static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; @@ -2311,7 +2311,7 @@ void GameMIDIMusic_OnChange(void) else { midi_disabled = true; - if (S_MusicType() == MU_MID) + if (S_MusicType() == MU_MID || S_MusicType() == MU_MID_EX) { if (digital_disabled) S_StopMusic();