From 8cbacdeda7e947a071b626eb67040cbbc8330fa8 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sat, 25 Jan 2025 23:52:53 +0100 Subject: [PATCH 1/6] Kart skin compatibility --- src/info.c | 1 + src/info/sprite2.h | 2 + src/r_skins.c | 121 ++++++++++++++++++++++++++++++++++++++++++--- src/r_skins.h | 1 + src/r_things.cpp | 24 +++++++++ src/r_things.h | 1 + src/w_wad.c | 34 ++++++++++++- 7 files changed, 175 insertions(+), 9 deletions(-) diff --git a/src/info.c b/src/info.c index a9f8ec64e..4982dc6e4 100644 --- a/src/info.c +++ b/src/info.c @@ -79,6 +79,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = { 0, // SPR2_SIGN 0, // SPR2_XTRA + 0, // SPR2_KART }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) diff --git a/src/info/sprite2.h b/src/info/sprite2.h index 0440bad64..de564fc95 100644 --- a/src/info/sprite2.h +++ b/src/info/sprite2.h @@ -22,3 +22,5 @@ _(DEAD) // Dead _(SIGN) // Finish signpost _(XTRA) // Three Faces of Darkness + +_(KART) // Extra frames from Kart skins diff --git a/src/r_skins.c b/src/r_skins.c index 0ef47fd61..7c545a04c 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -109,6 +109,9 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->flags = 0; strcpy(skin->realname, "Someone"); + strncpy(skin->facerank, "MISSING", 9); + strncpy(skin->facewant, "MISSING", 9); + strncpy(skin->facemmap, "MISSING", 9); skin->starttranscolor = 96; skin->prefcolor = SKINCOLOR_GREEN; skin->supercolor = SKINCOLOR_SUPERGOLD1; @@ -396,6 +399,37 @@ static UINT16 W_CheckForPatchSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) return INT16_MAX; // not found } +#define NUMKARTFRAMES 19 +#define S(f, s) { f - 'A', SPR2_##s }, +static UINT8 KART_TO_SPR2[][2] = { + S('A', STIN) + S('B', STIN) + S('C', STIL) + S('D', STIL) + S('E', STIR) + S('F', STIR) + S('J', SLWN) + S('G', SLWN) + S('K', SLWL) + S('H', SLWL) + S('L', SLWR) + S('I', SLWR) + S('A', FSTN) + S('J', FSTN) + S('C', FSTL) + S('K', FSTL) + S('E', FSTR) + S('L', FSTR) + S('M', DRLN) + S('N', DRLN) + S('O', DRRN) + S('P', DRRN) + S('Q', SPIN) + S('R', KART) + S('S', SIGN) +}; +#undef S + static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin) { UINT16 newlastlump; @@ -427,20 +461,88 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski *lastlump = newlastlump; // okay, make the normal sprite set loading end there }*/ - // load all sprite sets we are aware of... for normal stuff. - for (sprite2 = 0; sprite2 < free_spr2; sprite2++) - R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump); + if (!wadfiles[wadnum]->compatmode) + { + // load all sprite sets we are aware of... for normal stuff. + for (sprite2 = 0; sprite2 < free_spr2; sprite2++) + R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump); + } + else + { + // okay, now we have to get fancy... + // first, just dump all the frames in a temporary def + size_t i; + spritedef_t *sd; + spriteframe_t *sf; + spritedef_t tmp = {}; + const char *sprname = W_CheckNameForNumPwad(wadnum, *lump); + R_AddSingleSpriteDef(sprname, &tmp, wadnum, *lump, *lastlump); + + if (tmp.numframes < NUMKARTFRAMES) + I_Error("R_LoadSkinSprites: too few frames for kart skin"); + + // now shuffle them around to fit the new SPR2 system + // iterate over KART_TO_SPR2, then add any excess frames to SPR2_KART +#define SPR2COUNT sizeof(KART_TO_SPR2)/sizeof(*KART_TO_SPR2) + for (i = 0; i < SPR2COUNT - NUMKARTFRAMES + tmp.numframes; i++) + { + boolean excess = i >= SPR2COUNT; + sf = &tmp.spriteframes[excess ? i - SPR2COUNT + NUMKARTFRAMES : KART_TO_SPR2[i][0]]; + sd = &skin->sprites[excess ? SPR2_KART : KART_TO_SPR2[i][1]]; + sd->spriteframes = Z_Realloc(sd->spriteframes, sizeof(*sd->spriteframes) * (sd->numframes+1), PU_STATIC, NULL); + sd->spriteframes[sd->numframes++] = *sf; + } + Z_Free(tmp.spriteframes); +#undef SPR2COUNT + + // now we have to rotate the drift frames. i hate this. + sd = &skin->sprites[SPR2_DRRN]; + for (i = 0; i < sd->numframes; i++) + { + sf = &sd->spriteframes[i]; + if (sf->rotate != SRF_3D) + continue; + lumpnum_t lastpat = sf->lumppat[7]; + size_t lastid = sf->lumpid[7]; + for (int r = 7; r >= 1; r--) + { + sf->lumppat[r] = sf->lumppat[r-1]; + sf->lumpid[r] = sf->lumpid[r-1]; + } + sf->lumppat[0] = lastpat; + sf->lumpid[0] = lastid; + } + sd = &skin->sprites[SPR2_DRLN]; + for (i = 0; i < sd->numframes; i++) + { + sf = &sd->spriteframes[i]; + if (sf->rotate != SRF_3D) + continue; + lumpnum_t firstpat = sf->lumppat[0]; + size_t firstid = sf->lumpid[0]; + for (int r = 0; r < 8; r++) + { + sf->lumppat[r] = sf->lumppat[r+1]; + sf->lumpid[r] = sf->lumpid[r+1]; + } + sf->lumppat[7] = firstpat; + sf->lumpid[7] = firstid; + } + + R_AddKartFaces(skin); + } if (skin->sprites[0].numframes == 0) I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]); } +#undef NUMKARTFRAMES // returns whether found appropriate property -static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) +static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value, boolean compat) { // custom translation table if (!stricmp(stoken, "startcolor")) - skin->starttranscolor = atoi(value); + skin->starttranscolor = compat ? R_GetPaletteRemap(atoi(value)) : atoi(value); #define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value); // character type identification @@ -492,6 +594,11 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(MACHINE) #undef GETFLAG +#define GETPATCH(field) else if (compat && !stricmp(stoken, #field)) strncpy(skin->field, value, 8); + GETPATCH(facerank) + GETPATCH(facewant) + GETPATCH(facemmap) + else // let's check if it's a sound, otherwise error out { boolean found = false; @@ -667,7 +774,7 @@ void R_AddSkins(UINT16 wadnum) pos++; } } - else if (!R_ProcessPatchableFields(skin, stoken, value)) + else if (!R_ProcessPatchableFields(skin, stoken, value, wadfiles[wadnum]->compatmode)) CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); next_token: @@ -822,7 +929,7 @@ void R_PatchSkins(UINT16 wadnum) pos++; } } - else if (!R_ProcessPatchableFields(skin, stoken, value)) + else if (!R_ProcessPatchableFields(skin, stoken, value, wadfiles[wadnum]->compatmode)) CONS_Debug(DBG_SETUP, "R_PatchSkins: Unknown keyword '%s' in P_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); } diff --git a/src/r_skins.h b/src/r_skins.h index 102bef3c0..c7bef3c1a 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -42,6 +42,7 @@ struct skin_t skinflags_t flags; char realname[SKINNAMESIZE+1]; // Display name for level completion. + char facerank[9], facewant[9], facemmap[9]; // Arbitrarily named patch lumps // SRB2kart UINT8 kartspeed; diff --git a/src/r_things.cpp b/src/r_things.cpp index 0c2795169..0683f9efc 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -249,6 +249,30 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch sprtemp[frame].flip &= ~(1<sprites[SPR2_XTRA]; + for (size_t f = 0; f < NUMFACES; f++) + { + lumpnum_t lumpnum = W_CheckNumForName(reinterpret_cast(skin) + KART_FACES[f]); // how do you do, fellow C++ers? + if (lumpnum == LUMPERROR) + I_Error("R_AddKartFaces: missing patch %s for skin %s", reinterpret_cast(skin) + KART_FACES[f], skin->name); + R_InstallSpriteLump(WADFILENUM(lumpnum), LUMPNUM(lumpnum), numspritelumps++, f, 0, 0); + } + sd->numframes = NUMFACES; + sd->spriteframes = static_cast(Z_Realloc(sd->spriteframes, sizeof(spriteframe_t)*NUMFACES, PU_STATIC, NULL)); + M_Memcpy(sd->spriteframes, sprtemp, sizeof(spriteframe_t)*NUMFACES); +} +#undef NUMFACES + // Install a single sprite, given its identifying name (4 chars) // // (originally part of R_AddSpriteDefs) diff --git a/src/r_things.h b/src/r_things.h index 0fa20666b..c51ab69ca 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -31,6 +31,7 @@ extern "C" { #define FEETADJUST (4<= 18; +#else + return false; +#endif +} + // try to figure out if a PK3 file needs compatmode enabled (palette remap) static inline boolean CheckCompatZip(UINT16 wadnum) { - if (CheckCompatFilename(wadfiles[wadnum]->filename)) + if (CheckCompatFilename(wadfiles[wadnum]->filename) || CheckCompatSkins(wadnum)) return true; // assume RR/2.2 for PK3s so basegame assets work @@ -311,7 +341,7 @@ static inline boolean CheckCompatZip(UINT16 wadnum) // ditto, but for WADs static inline boolean CheckCompatWad(UINT16 wadnum) { - if (CheckCompatFilename(wadfiles[wadnum]->filename)) + if (CheckCompatFilename(wadfiles[wadnum]->filename) || CheckCompatSkins(wadnum)) return true; // assume Kart/2.1 for WADs so basegame assets work From 4288d0d3feadeb283d12c73af531b6187b5058a3 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 26 Jan 2025 03:04:18 +0100 Subject: [PATCH 2/6] Update mobjlib frame/sprite setters for compatmode --- src/lua_mobjlib.c | 124 ++++++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 55 deletions(-) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index c3f08d52f..05826d911 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -501,6 +501,69 @@ static int mobj_get(lua_State *L) return 1; } +#define F(x) case x - 'A': +static void frame2spr2(mobj_t *mo, UINT32 inframe) +{ + UINT8 spr2, outframe = 0; + switch (inframe & FF_FRAMEMASK) + { + F('A') F('B') + spr2 = SPR2_STIN; + outframe = inframe & 1; + break; + F('C') F('D') + spr2 = SPR2_STIL; + outframe = inframe & 1; + break; + F('E') F('F') + spr2 = SPR2_STIR; + outframe = inframe & 1; + break; + F('G') + spr2 = SPR2_SLWN; + break; + F('H') + spr2 = SPR2_SLWL; + break; + F('I') + spr2 = SPR2_SLWR; + break; + F('J') + spr2 = SPR2_FSTN; + break; + F('K') + spr2 = SPR2_FSTL; + break; + F('L') + spr2 = SPR2_FSTR; + break; + F('M') F('N') + spr2 = SPR2_DRLN; + outframe = inframe & 1; + break; + F('O') F('P') + spr2 = SPR2_DRRN; + outframe = inframe & 1; + break; + F('Q') + spr2 = SPR2_SPIN; + break; + F('R') + spr2 = SPR2_KART; + break; + F('S') + spr2 = SPR2_SIGN; + break; + default: + spr2 = SPR2_KART; + outframe = inframe - 18; // not 19! frame 0 is squish + break; + } + mo->frame = (inframe & ~FF_FRAMEMASK) | outframe; + mo->sprite2 = P_GetSkinSprite2((skin_t *)mo->skin, spr2, mo->player); +} +#undef F + #define NOSET luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly.", mobj_opt[field]) #define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_SetOrigin") ", or " LUA_QL("P_MoveOrigin") " instead.", mobj_opt[field]) static int mobj_set(lua_State *L) @@ -559,64 +622,15 @@ static int mobj_set(lua_State *L) mo->rollangle = luaL_checkangle(L, 3); break; case mobj_sprite: - mo->sprite = luaL_checkinteger(L, 3); - if (mo->sprite == SPR_PLAY) - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_STIN, mo->player); + spritenum_t newsprite = luaL_checkinteger(L, 3); + if (lua_compatmode && mo->sprite != SPR_PLAY && newsprite == SPR_PLAY) + frame2spr2(mo, mo->frame); + mo->sprite = newsprite; break; case mobj_frame: // Check for SPR2 - if (mo->sprite == SPR_PLAY) - { - UINT32 frame = (UINT32)luaL_checkinteger(L, 3); - switch (frame) - { - case 0: - case 1: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_STIN, mo->player); - break; - case 2: - case 3: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_STIL, mo->player); - break; - case 4: - case 5: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_STIR, mo->player); - break; - case 6: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_SLWN, mo->player); - break; - case 7: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_SLWL, mo->player); - break; - case 8: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_SLWR, mo->player); - break; - case 9: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_FSTN, mo->player); - break; - case 10: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_FSTL, mo->player); - break; - case 11: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_FSTR, mo->player); - break; - case 12: - case 13: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_DRLN, mo->player); - break; - case 14: - case 15: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_DRRN, mo->player); - break; - case 16: - case 17: // squish technically doesnt really exist - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_SPIN, mo->player); - break; - case 18: - mo->sprite2 = P_GetSkinSprite2(((skin_t *)mo->skin), SPR2_SIGN, mo->player); - break; - } - } + if (lua_compatmode && mo->sprite == SPR_PLAY) + frame2spr2(mo, (UINT32)luaL_checkinteger(L, 3)); else mo->frame = (UINT32)luaL_checkinteger(L, 3); break; From 229f3cc2e1643bc768b28a1154b65a74117ffa9a Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 26 Jan 2025 15:48:15 -0500 Subject: [PATCH 3/6] Use chars.kart --- src/config.h.in | 3 ++- src/d_main.cpp | 6 +++--- src/d_netfil.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/config.h.in b/src/config.h.in index a4b5ee3ad..bd38e2d6c 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -12,13 +12,14 @@ /* Manually defined asset hashes * Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets * Last updated 2020 / 08 / 30 - Kart v1.3 - patch.kart + * updated 2025 - BlanKart Indev - */ #define ASSET_HASH_MAIN_PK3 "daf9a1a67b5e465c13789e96a09f7171" #define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7" #define ASSET_HASH_GFX_KART "06f86ee16136eb8a7043b15001797034" #define ASSET_HASH_TEXTURES_KART "abb53d56aba47c3a8cb0f764da1c8b80" -#define ASSET_HASH_CHARS_PK3 "bf014478cdda5e9208e3dea3c51f58c5" +#define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964" #define ASSET_HASH_MAPS_KART "d051e55141ba736582228c456953cd98" #define ASSET_HASH_FOLLOWERS_PK3 "00000000000000000000000000000000" #ifdef USE_PATCH_FILE diff --git a/src/d_main.cpp b/src/d_main.cpp index dc947187c..023c56ecc 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1191,7 +1191,7 @@ static void IdentifyVersion(void) #define PATCHNAME "patch.pk3" #define MUSICNAME "music.kart" #define FOLLOWERSNAME "followers.pk3" -#define CHARSNAME "chars.pk3" +#define CHARSNAME "chars.kart" #define GRAPHICSNAME "gfx.kart" #define SOUNDSNAME "sounds.kart" @@ -1487,7 +1487,7 @@ void D_SRB2Main(void) mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAIN_PK3); // main.pk3 mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); // gfx.pk3 mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_KART); // textures.pk3 - mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_PK3); // chars.pk3 + mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); // chars.kart mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); // maps.pk3 -- 4 - If you touch this, make sure to touch up the majormods stuff below. //mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_FOLLOWERS_PK3); // followers.pk3 #ifdef USE_PATCH_FILE @@ -1497,7 +1497,7 @@ void D_SRB2Main(void) mainwads++; // main.pk3 mainwads++; // gfx.kart mainwads++; // textures.kart - mainwads++; // chars.pk3 + mainwads++; // chars.kart mainwads++; // maps.kart //mainwads++; // followers.pk3 #ifdef USE_PATCH_FILE diff --git a/src/d_netfil.c b/src/d_netfil.c index 5d76a5ef6..f3c293629 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1422,7 +1422,7 @@ void PT_FileFragment(void) || !strcmp(filename, "srb2.srb") || !strcmp(filename, "gfx.kart") || !strcmp(filename, "textures.kart") - || !strcmp(filename, "chars.pk3") + || !strcmp(filename, "chars.kart") || !strcmp(filename, "maps.kart") || !strcmp(filename, "patch.pk3") || !strcmp(filename, "sounds.kart") From 247e60442b7dc1c3f7bae150fef4fd940bf25870 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Sun, 26 Jan 2025 21:55:17 +0100 Subject: [PATCH 4/6] I HATE THAT HEDGEHOG!!!!!!!!! --- src/r_skins.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/r_skins.c b/src/r_skins.c index 7c545a04c..c13e54e8f 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -129,6 +129,8 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->soundsid[S_sfx[i].skinsound] = i; } +static void R_IHateThatHedgehog(UINT16 wadnum); + // // Initialize the basic skins // @@ -151,6 +153,8 @@ void R_InitSkins(void) for (i = 0; i < numwadfiles; i++) { + if (i == 4) // chars.kart + R_IHateThatHedgehog((UINT16)i); R_AddSkins((UINT16)i); R_PatchSkins((UINT16)i); R_LoadSpriteInfoLumps(i, wadfiles[i]->numlumps); @@ -537,6 +541,41 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski } #undef NUMKARTFRAMES +static void R_IHateThatHedgehog(UINT16 wadnum) +{ + skin_t *skin = &skins[0]; + Sk_SetDefaultValue(skin); + skin->wadnum = wadnum; + strcpy(skin->name, "sonic"); + strcpy(skin->realname, "Sonic"); + strcpy(skin->facerank, "PLAYRANK"); + strcpy(skin->facewant, "PLAYWANT"); + strcpy(skin->facemmap, "PLAYMMAP"); + skin->prefcolor = SKINCOLOR_BLUE; + skin->starttranscolor = R_GetPaletteRemap(160); + skin->kartspeed = 8; + skin->kartweight = 2; + + UINT16 lump = W_CheckNumForNamePwad("S_START", wadnum, 0); + if (lump == INT16_MAX) + I_Error("R_IHateThatHedgehog: could not find the hedgehog"); + R_LoadSkinSprites(wadnum, &lump, &(UINT16){}, skin); + +#ifdef SKINVALUES + skin_cons_t[0].value = 0; + skin_cons_t[0].strvalue = skin->name; +#endif + Forceskin_cons_t[1].value = 0; + Forceskin_cons_t[1].strvalue = skin->name; + +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_AddPlayerModel(0); +#endif + + numskins = (UINT8)('r'+'a'+'c'+'e'+' '+'a'+'s'+' '+'a'+' '+'r'+'i'+'n'+'g'+'!'); +} + // returns whether found appropriate property static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value, boolean compat) { From 1b25b4283595af431a73e35c591bd114d50de9e4 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 26 Jan 2025 17:57:58 -0500 Subject: [PATCH 5/6] Add new flags for toggling death effects --- src/d_player.h | 2 + src/p_inter.c | 116 ++++++++++++++++++++++++++----------------------- src/p_mobj.c | 5 +++ src/r_skins.c | 4 ++ 4 files changed, 73 insertions(+), 54 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 5d71a2715..b3baa57cf 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -41,6 +41,8 @@ typedef enum { SF_HIRES = 1, // Draw the sprite at different size? SF_MACHINE = 1<<1, // Beep boop. Are you a robot? + SF_NOGIBS = 1<<2, // Does this kart smash into pieces? + SF_OLDDEATH = 1<<3, // Kart V1 styled death animation // free up to and including 1<<31 } skinflags_t; diff --git a/src/p_inter.c b/src/p_inter.c index 902168f96..0d4e173a8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1394,76 +1394,84 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->fuse = 2*TICRATE; // timer before mobj disappears from view (even if not an actual player) target->momx = target->momy = target->momz = 0; - angle_t playerFlingAngle; - angle_t kartFlingAngle; - - if (source && !P_MobjWasRemoved(source)) + if (target->player && !(skins[target->player->skin].flags & SF_NOGIBS)) { - playerFlingAngle = kartFlingAngle = R_PointToAngle2( - source->x - source->momx, source->y - source->momy, - target->x, target->y - ); - } - else - { - kartFlingAngle = target->angle; + angle_t playerFlingAngle; + angle_t kartFlingAngle; - if (P_RandomByte() & 1) + if (source && !P_MobjWasRemoved(source)) { - kartFlingAngle -= ANGLE_45; + playerFlingAngle = kartFlingAngle = R_PointToAngle2( + source->x - source->momx, source->y - source->momy, + target->x, target->y + ); } else { - kartFlingAngle += ANGLE_45; + kartFlingAngle = target->angle; + + if (P_RandomByte() & 1) + { + kartFlingAngle -= ANGLE_45; + } + else + { + kartFlingAngle += ANGLE_45; + } + + playerFlingAngle = kartFlingAngle + ANGLE_180; } - playerFlingAngle = kartFlingAngle + ANGLE_180; - } + // Spawn kart frame + mobj_t *kart = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_KART_LEFTOVER); - // Spawn kart frame - mobj_t *kart = P_SpawnMobjFromMobj(target, 0, 0, 0, MT_KART_LEFTOVER); - - if (kart && !P_MobjWasRemoved(kart)) - { - kart->angle = target->angle; - kart->color = target->color; - kart->extravalue1 = target->player->kartweight; - kart->fuse = 2*TICRATE; - - // Copy interp data - kart->old_angle = target->old_angle; - kart->old_x = target->old_x; - kart->old_y = target->old_y; - kart->old_z = target->old_z; - - P_InstaThrust(kart, kartFlingAngle, 1 * kart->scale); - P_SetObjectMomZ(kart, 10*FRACUNIT, false); - - const angle_t aOffset = ANGLE_22h; - - UINT8 i; - angle_t tireAngle; - mobj_t *tire; - - // Spawn tires - tireAngle = kartFlingAngle - ANGLE_90 - ANGLE_22h; - for (i = 0; i < 4; i++) + if (kart && !P_MobjWasRemoved(kart)) { - if (i == 2) tireAngle += ANGLE_90; + kart->angle = target->angle; + kart->color = target->color; + kart->extravalue1 = target->player->kartweight; + kart->fuse = 2*TICRATE; - tire = P_SpawnMobjFromMobj(kart, 0, 0, 0, MT_KART_TIRE); - tire->fuse = 2*TICRATE; + // Copy interp data + kart->old_angle = target->old_angle; + kart->old_x = target->old_x; + kart->old_y = target->old_y; + kart->old_z = target->old_z; - tire->angle = tireAngle; - P_InstaThrust(tire, tireAngle, 3 * tire->scale); - P_SetObjectMomZ(tire, 10*FRACUNIT, false); + P_InstaThrust(kart, kartFlingAngle, 1 * kart->scale); + P_SetObjectMomZ(kart, 10*FRACUNIT, false); - tireAngle += (aOffset * 2); + const angle_t aOffset = ANGLE_22h; + + UINT8 i; + angle_t tireAngle; + mobj_t *tire; + + // Spawn tires + tireAngle = kartFlingAngle - ANGLE_90 - ANGLE_22h; + for (i = 0; i < 4; i++) + { + if (i == 2) tireAngle += ANGLE_90; + + tire = P_SpawnMobjFromMobj(kart, 0, 0, 0, MT_KART_TIRE); + tire->fuse = 2*TICRATE; + + tire->angle = tireAngle; + P_InstaThrust(tire, tireAngle, 3 * tire->scale); + P_SetObjectMomZ(tire, 10*FRACUNIT, false); + + tireAngle += (aOffset * 2); + } } + + P_InstaThrust(target, playerFlingAngle, 4 * target->scale); + P_SetObjectMomZ(target, 14*FRACUNIT, false); } - P_InstaThrust(target, playerFlingAngle, 4 * target->scale); - P_SetObjectMomZ(target, 14*FRACUNIT, false); + if (target->player && (skins[target->player->skin].flags & SF_OLDDEATH)) + { + P_SetObjectMomZ(target, 14*FRACUNIT, false); + } P_PlayDeathSound(target); } diff --git a/src/p_mobj.c b/src/p_mobj.c index f62ef15d1..1e0f5d89a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6427,6 +6427,11 @@ static boolean P_MobjDeadThink(mobj_t *mobj) else // Apply gravity to fall downwards. { P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + + if (mobj->player && (skins[mobj->player->skin].flags && SF_OLDDEATH)) + { + mobj->player->drawangle -= ANGLE_22h; + } } break; case MT_METALSONIC_RACE: diff --git a/src/r_skins.c b/src/r_skins.c index c13e54e8f..aa722a168 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -429,6 +429,7 @@ static UINT8 KART_TO_SPR2[][2] = { S('O', DRRN) S('P', DRRN) S('Q', SPIN) + S('Q', DEAD) S('R', KART) S('S', SIGN) }; @@ -534,6 +535,9 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski } R_AddKartFaces(skin); + + skin->flags |= SF_OLDDEATH|SF_NOGIBS; + } if (skin->sprites[0].numframes == 0) From ef635dd7f44df5da7dc152d17cd55aaec568a08c Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Mon, 27 Jan 2025 02:42:26 +0100 Subject: [PATCH 6/6] Always use drift state (and shallower angle) for sliptide in compatmode --- src/k_kart.c | 2 +- src/r_fps.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 8fcd48c15..e179e5893 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2602,7 +2602,7 @@ void K_KartMoveAnimation(player_t *player) } // Sliptides: drift -> lookback frames - if (abs(player->aizdriftturn) >= ANGLE_90) + if (abs(player->aizdriftturn) >= ANGLE_90 && !wadfiles[((skin_t *)player->mo->skin)->wadnum]->compatmode) { destGlanceDir = -(2*intsign(player->aizdriftturn)); player->glanceDir = destGlanceDir; diff --git a/src/r_fps.c b/src/r_fps.c index 125937ad5..1fedc1831 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -15,6 +15,7 @@ #include "r_fps.h" #include "r_main.h" +#include "r_skins.h" #include "g_game.h" #include "i_video.h" #include "r_plane.h" @@ -287,6 +288,9 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) if (mobj->player && mobj->player->aizdriftturn) { addangle += mobj->player->aizdriftturn; + if (mobj->skin && wadfiles[((skin_t *)mobj->skin)->wadnum]->compatmode) + // don't turn too much in compatmode + addangle = (INT32)addangle / 4; } if (mobj->state == &states[S_KART_DRIFT_L] || mobj->state == &states[S_KART_DRIFT_L_OUT]