From f8afb52b1a6656b110ec1a353f139403de8b6659 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 19 May 2025 18:28:11 -0700 Subject: [PATCH 1/6] Add Lightning Shield states --- src/deh_tables.c | 7 +++++++ src/info.c | 36 ++++++++++++++++++++++++++++++++++++ src/info.h | 10 ++++++++++ 3 files changed, 53 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 8369624ec..3d517c8ac 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1993,6 +1993,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_LIGHTNINGSHIELD23", "S_LIGHTNINGSHIELD24", + // Lightning Shield Visuals + "S_THNC1", + "S_THNA1", + "S_THNC2", + "S_THNB1", + // Bubble Shield "S_BUBBLESHIELD1", "S_BUBBLESHIELD2", @@ -3624,6 +3630,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_MANTARING", // Juicebox for SPB "MT_LIGHTNINGSHIELD", // Shields + "MT_LIGHTNINGSHIELD_VISUAL", "MT_BUBBLESHIELD", "MT_BUBBLESHIELD_VISUAL", "MT_FLAMESHIELD", diff --git a/src/info.c b/src/info.c index 1973faecc..03937aa7d 100644 --- a/src/info.c +++ b/src/info.c @@ -375,6 +375,9 @@ char sprnames[NUMSPRITES + 1][5] = "TRIS", // SPB Manta Ring start "TRNQ", // SPB Manta Ring loop "THNS", // Lightning Shield + "THNC", // Lightning Shield Top Flash + "THNA", // Lightning Shield Top Swoosh + "THNB", // Lightning Shield Bottom Swoosh "BUBS", // Bubble Shield (not Bubs) "BUBA", // Bubble Shield Outline "BUBB", // Bubble Shield Top Wave @@ -2534,6 +2537,12 @@ state_t states[NUMSTATES] = {SPR_THNS, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD23}, // S_LIGHTNINGSHIELD22 {SPR_THNS, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD24}, // S_LIGHTNINGSHIELD23 {SPR_THNS, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_LIGHTNINGSHIELD1}, // S_LIGHTNINGSHIELD24 + // + // Lightning Shield Visuals + {SPR_THNC, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, 11, {NULL}, 10, 1, S_THNA1}, // S_THNC1 + {SPR_THNA, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, 44, {NULL}, 43, 1, S_THNC2}, // S_THNA1 + {SPR_THNC, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, 11, {NULL}, 10, 1, S_THNB1}, // S_THNC2 + {SPR_THNB, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, 43, {NULL}, 42, 1, S_THNC1}, // S_THNB1 {SPR_BUBS, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_BUBBLESHIELD2}, // S_BUBBLESHIELD1 {SPR_BUBS, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_BUBBLESHIELD3}, // S_BUBBLESHIELD2 @@ -15382,6 +15391,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_LIGHTNINGSHIELD_VISUAL + -1, // doomednum + S_THNC1, // spawnstate + 1000, // spawnhealth + S_NULL, // 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 + 28*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_BUBBLESHIELD -1, // doomednum S_BUBBLESHIELD1, // spawnstate diff --git a/src/info.h b/src/info.h index 9b26cad1c..ea9825f6b 100644 --- a/src/info.h +++ b/src/info.h @@ -914,6 +914,9 @@ typedef enum sprite SPR_TRIS, // SPB Manta Ring start SPR_TRNQ, // SPB Manta Ring loop SPR_THNS, // Thunder Shield + SPR_THNC, // Lightning Shield Top Flash + SPR_THNA, // Lightning Shield Top Swoosh + SPR_THNB, // Lightning Shield Bottom Swoosh SPR_BUBS, // Bubble Shield (not Bubs) SPR_BUBA, // Bubble Shield Outline SPR_BUBB, // Bubble Shield Top Wave @@ -3029,6 +3032,12 @@ typedef enum state S_LIGHTNINGSHIELD23, S_LIGHTNINGSHIELD24, + // Lightning Shield Visuals + S_THNC1, + S_THNA1, + S_THNC2, + S_THNB1, + // Bubble Shield S_BUBBLESHIELD1, S_BUBBLESHIELD2, @@ -4687,6 +4696,7 @@ typedef enum mobj_type MT_MANTARING, // Juicebox for SPB MT_LIGHTNINGSHIELD, // Shields + MT_LIGHTNINGSHIELD_VISUAL, MT_BUBBLESHIELD, MT_BUBBLESHIELD_VISUAL, MT_FLAMESHIELD, From cccde157d46d4b3af9bce397a88ab04942a38d1a Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 19 May 2025 18:28:37 -0700 Subject: [PATCH 2/6] Add Flame Shield states --- src/deh_tables.c | 6 ++++++ src/info.c | 34 ++++++++++++++++++++++++++++++++++ src/info.h | 8 ++++++++ 3 files changed, 48 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 3d517c8ac..1ab94f7f4 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -2063,6 +2063,11 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_FLAMESHIELD17", "S_FLAMESHIELD18", + // Flame Shield Visuals + "S_FLMA1", + "S_FLMA2", + "S_FLMB1", + "S_FLAMESHIELDDASH1", "S_FLAMESHIELDDASH2", "S_FLAMESHIELDDASH3", @@ -3634,6 +3639,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_BUBBLESHIELD", "MT_BUBBLESHIELD_VISUAL", "MT_FLAMESHIELD", + "MT_FLAMESHIELD_VISUAL", "MT_FLAMESHIELDUNDERLAY", "MT_FLAMESHIELDPAPER", "MT_BUBBLESHIELDTRAP", diff --git a/src/info.c b/src/info.c index 03937aa7d..b18a256d1 100644 --- a/src/info.c +++ b/src/info.c @@ -386,6 +386,8 @@ char sprnames[NUMSPRITES + 1][5] = "BUBE", // Bubble Shield Underline "BWVE", // Bubble Shield waves "FLMS", // Flame Shield + "FLMA", // Flame Shield Top Layer + "FLMB", // Flame Shield Bottom Layer "FLMD", // Flame Shield dash "FLMP", // Flame Shield paper sprites "FLML", // Flame Shield speed lines @@ -2605,6 +2607,11 @@ state_t states[NUMSTATES] = {SPR_FLMS, FF_FULLBRIGHT|16, 2, {NULL}, 0, 0, S_FLAMESHIELD17}, // S_FLAMESHIELD16 {SPR_FLMS, FF_FULLBRIGHT|8, 2, {NULL}, 0, 0, S_FLAMESHIELD18}, // S_FLAMESHIELD17 {SPR_FLMS, FF_FULLBRIGHT|17, 2, {NULL}, 0, 0, S_FLAMESHIELD1}, // S_FLAMESHIELD18 + // + // Flame Shield Visuals + {SPR_FLMA, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE, 28, {NULL}, 27, 1, S_FLMA2}, // S_FLMA1 + {SPR_NULL, 0, 16, {NULL}, 0, 0, S_FLMA1}, // S_FLMA2 + {SPR_FLMB, FF_FULLBRIGHT|FF_ANIMATE, 44, {NULL}, 43, 1, S_FLMB1}, // S_FLMB1 {SPR_FLMD, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH2}, // S_FLAMESHIELDDASH1 {SPR_FLMD, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH3}, // S_FLAMESHIELDDASH2 @@ -15499,6 +15506,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_FLAMESHIELD_VISUAL + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // 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 + 28*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_FLAMESHIELDUNDERLAY -1, // doomednum S_FLAMESHIELDDASH2_UNDERLAY, // spawnstate diff --git a/src/info.h b/src/info.h index ea9825f6b..9ac1b6994 100644 --- a/src/info.h +++ b/src/info.h @@ -925,6 +925,8 @@ typedef enum sprite SPR_BUBE, // Bubble Shield Underline SPR_BWVE, // Bubble Shield waves SPR_FLMS, // Flame Shield + SPR_FLMA, // Flame Shield Top Layer + SPR_FLMB, // Flame Shield Bottom Layer SPR_FLMD, // Flame Shield dash SPR_FLMP, // Flame Shield paper sprites SPR_FLML, // Flame Shield speed lines @@ -3102,6 +3104,11 @@ typedef enum state S_FLAMESHIELD17, S_FLAMESHIELD18, + // Flame Shield Visuals + S_FLMA1, + S_FLMA2, + S_FLMB1, + S_FLAMESHIELDDASH1, S_FLAMESHIELDDASH2, S_FLAMESHIELDDASH3, @@ -4700,6 +4707,7 @@ typedef enum mobj_type MT_BUBBLESHIELD, MT_BUBBLESHIELD_VISUAL, MT_FLAMESHIELD, + MT_FLAMESHIELD_VISUAL, MT_FLAMESHIELDUNDERLAY, MT_FLAMESHIELDPAPER, MT_BUBBLESHIELDTRAP, From 835785d94061eeaef107c8afe34b7b709f20512e Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 19 May 2025 18:29:19 -0700 Subject: [PATCH 3/6] Make Lightning Shield bolts additive --- src/info.c | 82 +++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/info.c b/src/info.c index b18a256d1..f51346127 100644 --- a/src/info.c +++ b/src/info.c @@ -2941,54 +2941,54 @@ state_t states[NUMSTATES] = // Oh no it's annoying lightning states....... // Lightning Sparks (it's the ones we'll use for the radius) - {SPR_KSPK, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK2}, // S_KSPARK1 - {SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK3}, // S_KSPARK2 - {SPR_KSPK, FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK4}, // S_KSPARK3 - {SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK5}, // S_KSPARK4 - {SPR_KSPK, FF_FULLBRIGHT|2, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK6}, // S_KSPARK5 - {SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK7}, // S_KSPARK6 - {SPR_KSPK, FF_FULLBRIGHT|3, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK8}, // S_KSPARK7 - {SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK9}, // S_KSPARK8 - {SPR_KSPK, FF_TRANS40|FF_FULLBRIGHT|4, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK10}, // S_KSPARK9 - {SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK11}, // S_KSPARK10 - {SPR_KSPK, FF_TRANS50|FF_FULLBRIGHT|5, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK12}, // S_KSPARK11 - {SPR_NULL, FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK13}, // S_KSPARK12 - {SPR_KSPK, FF_TRANS60|FF_FULLBRIGHT|6, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_KSPARK13 + {SPR_KSPK, FF_ADD|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK2}, // S_KSPARK1 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK3}, // S_KSPARK2 + {SPR_KSPK, FF_ADD|FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK4}, // S_KSPARK3 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK5}, // S_KSPARK4 + {SPR_KSPK, FF_ADD|FF_FULLBRIGHT|2, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK6}, // S_KSPARK5 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK7}, // S_KSPARK6 + {SPR_KSPK, FF_ADD|FF_FULLBRIGHT|3, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK8}, // S_KSPARK7 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK9}, // S_KSPARK8 + {SPR_KSPK, FF_ADD|FF_TRANS40|FF_FULLBRIGHT|4, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK10}, // S_KSPARK9 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK11}, // S_KSPARK10 + {SPR_KSPK, FF_ADD|FF_TRANS50|FF_FULLBRIGHT|5, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK12}, // S_KSPARK11 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 1, {A_LightningFollowPlayer}, 0, 0, S_KSPARK13}, // S_KSPARK12 + {SPR_KSPK, FF_ADD|FF_TRANS60|FF_FULLBRIGHT|6, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_KSPARK13 // The straight bolt... - {SPR_LZI1, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO12}, // S_LZIO11 - {SPR_NULL, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO13}, // S_LZIO12 - {SPR_LZI1, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO14}, // S_LZIO13 - {SPR_LZI1, FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO15}, // S_LZIO14 - {SPR_NULL, FF_FULLBRIGHT, 4, {A_LightningFollowPlayer}, 0, 0, S_LZIO16}, // S_LZIO15 - {SPR_LZI1, FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO17}, // S_LZIO16 + {SPR_LZI1, FF_ADD|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO12}, // S_LZIO11 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO13}, // S_LZIO12 + {SPR_LZI1, FF_ADD|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO14}, // S_LZIO13 + {SPR_LZI1, FF_ADD|FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO15}, // S_LZIO14 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 4, {A_LightningFollowPlayer}, 0, 0, S_LZIO16}, // S_LZIO15 + {SPR_LZI1, FF_ADD|FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO17}, // S_LZIO16 {SPR_NULL, 0, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO18}, // S_LZIO17 - {SPR_LZI1, FF_TRANS50|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO19}, // S_LZIO18 - {SPR_LZI1, FF_TRANS70|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_LZIO19 + {SPR_LZI1, FF_ADD|FF_TRANS50|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO19}, // S_LZIO18 + {SPR_LZI1, FF_ADD|FF_TRANS70|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_LZIO19 - {SPR_NULL, FF_FULLBRIGHT, 6, {A_LightningFollowPlayer}, 0, 0, S_LZIO22}, // S_LZIO21 - {SPR_LZI2, FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO23}, // S_LZIO22 - {SPR_LZI2, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO24}, // S_LZIO23 - {SPR_NULL, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO25}, // S_LZIO24 - {SPR_NULL, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO26}, // S_LZIO25 - {SPR_NULL, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO27}, // S_LZIO26 - {SPR_LZI2, FF_TRANS30|FF_FULLBRIGHT|2, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO28}, // S_LZIO27 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 6, {A_LightningFollowPlayer}, 0, 0, S_LZIO22}, // S_LZIO21 + {SPR_LZI2, FF_ADD|FF_FULLBRIGHT|1, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO23}, // S_LZIO22 + {SPR_LZI2, FF_ADD|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO24}, // S_LZIO23 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO25}, // S_LZIO24 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO26}, // S_LZIO25 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO27}, // S_LZIO26 + {SPR_LZI2, FF_ADD|FF_TRANS30|FF_FULLBRIGHT|2, 2, {A_LightningFollowPlayer}, 0, 0, S_LZIO28}, // S_LZIO27 {SPR_NULL, 0, 4, {A_LightningFollowPlayer}, 0, 0, S_LZIO29}, // S_LZIO28 - {SPR_LZI2, FF_TRANS70|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_LZIO29 + {SPR_LZI2, FF_ADD|FF_TRANS70|FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_NULL}, // S_LZIO29 // The slanted bolt. Man these states are boring as all heck to do. - {SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT2}, // S_KLIT1 - {SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT3}, // S_KLIT2 - {SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|1, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT4}, // S_KLIT3 - {SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT5}, // S_KLIT4 - {SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|2, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT6}, // S_KLIT5 - {SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT7}, // S_KLIT6 - {SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|3, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT8}, // S_KLIT7 - {SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT9}, // S_KLIT8 - {SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|4, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT10}, // S_KLIT9 - {SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT11}, // S_KLIT10 - {SPR_KLIT, FF_FULLBRIGHT|FF_PAPERSPRITE|5, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT12}, // S_KLIT11 - {SPR_NULL, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT1}, // S_KLIT12 + {SPR_KLIT, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT2}, // S_KLIT1 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT3}, // S_KLIT2 + {SPR_KLIT, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE|1, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT4}, // S_KLIT3 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT5}, // S_KLIT4 + {SPR_KLIT, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE|2, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT6}, // S_KLIT5 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT7}, // S_KLIT6 + {SPR_KLIT, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE|3, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT8}, // S_KLIT7 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT9}, // S_KLIT8 + {SPR_KLIT, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE|4, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT10}, // S_KLIT9 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT11}, // S_KLIT10 + {SPR_KLIT, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE|5, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT12}, // S_KLIT11 + {SPR_NULL, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {A_LightningFollowPlayer}, 0, 0, S_KLIT1}, // S_KLIT12 {SPR_FZSM, 0, 4, {NULL}, 0, 0, S_FZEROSMOKE2}, // S_FZEROSMOKE1 {SPR_FZSM, 1, 4, {NULL}, 0, 0, S_FZEROSMOKE3}, // S_FZEROSMOKE2 From 3644f8afe732b02096fbf08544e4a7e3bb533ea3 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 19 May 2025 18:29:53 -0700 Subject: [PATCH 4/6] Add Lightning Shield visual object --- src/info.c | 2 +- src/k_kart.c | 2 + src/k_objects.h | 4 ++ src/objects/CMakeLists.txt | 1 + src/objects/lightning-shield.cpp | 74 ++++++++++++++++++++++++++++++++ src/p_mobj.c | 8 ++++ 6 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/objects/lightning-shield.cpp diff --git a/src/info.c b/src/info.c index f51346127..f8c30e83a 100644 --- a/src/info.c +++ b/src/info.c @@ -15373,7 +15373,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_LIGHTNINGSHIELD -1, // doomednum - S_LIGHTNINGSHIELD1, // spawnstate + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/k_kart.c b/src/k_kart.c index 4a00a1361..4879bd517 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -14059,6 +14059,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetTarget(&shield->target, player->mo); S_StartSound(player->mo, sfx_s3k41); player->curshield = KSHIELD_LIGHTNING; + + Obj_SpawnLightningShieldVisuals(shield); } if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) diff --git a/src/k_objects.h b/src/k_objects.h index ed0d62022..a3468cb8e 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -453,6 +453,10 @@ void K_DoBallhogAttack(player_t *player, UINT8 num_hogs); void Obj_SpawnBubbleShieldVisuals(mobj_t *source); boolean Obj_TickBubbleShieldVisual(mobj_t *mobj); +/* Lightning Shield */ +void Obj_SpawnLightningShieldVisuals(mobj_t *source); +boolean Obj_TickLightningShieldVisual(mobj_t *mobj); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 01c773b7d..1b9b26f0f 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -62,6 +62,7 @@ target_sources(SRB2SDL2 PRIVATE ballhog.cpp bubble-shield.cpp flybot767.c + lightning-shield.cpp ) add_subdirectory(versus) diff --git a/src/objects/lightning-shield.cpp b/src/objects/lightning-shield.cpp new file mode 100644 index 000000000..e08e4529c --- /dev/null +++ b/src/objects/lightning-shield.cpp @@ -0,0 +1,74 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2025 by James Robert Roman +// Copyright (C) 2025 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- + +#include "objects.hpp" + +#include "../tables.h" + +using namespace srb2::objects; + +namespace +{ + +struct Shield : Mobj +{ + void target() = delete; + Mobj* follow() const { return Mobj::target(); } + void follow(Mobj* n) { Mobj::target(n); } + + bool valid() const { return Mobj::valid(follow()); } +}; + +struct Visual : Mobj +{ + void target() = delete; + Shield* shield() const { return Mobj::target(); } + void shield(Shield* n) { Mobj::target(n); } + + bool valid() const { return Mobj::valid(shield()) && shield()->valid(); } + + static void spawn(Shield* shield) + { + if (!shield->valid()) + return; + + Visual* x = Mobj::spawn(shield->pos(), MT_LIGHTNINGSHIELD_VISUAL); + x->scale(5 * shield->follow()->scale() / 4); + x->shield(shield); + x->linkdraw(shield->follow()); + x->tick(); + } + + bool tick() + { + if (!valid()) + { + remove(); + return false; + } + + move_origin(shield()->pos()); + dispoffset = state()->num() == S_THNB1 ? -1 : 1; + + return true; + } +}; + +}; // namespace + +void Obj_SpawnLightningShieldVisuals(mobj_t *shield) +{ + Visual::spawn(static_cast(shield)); +} + +boolean Obj_TickLightningShieldVisual(mobj_t *mobj) +{ + return static_cast(mobj)->tick(); +} diff --git a/src/p_mobj.c b/src/p_mobj.c index c77e5b0ab..ea6bb86df 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6666,6 +6666,14 @@ static void P_MobjSceneryThink(mobj_t *mobj) } break; } + case MT_LIGHTNINGSHIELD_VISUAL: + { + if (!Obj_TickLightningShieldVisual(mobj)) + { + return; + } + break; + } default: if (mobj->fuse) { // Scenery object fuse! Very basic! From 2e57c5fd8bc67fb58a6769f20cc366a13f985187 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 19 May 2025 18:30:10 -0700 Subject: [PATCH 5/6] Add Flame Shield visual object --- src/info.c | 2 +- src/k_kart.c | 2 + src/k_objects.h | 4 ++ src/objects/CMakeLists.txt | 1 + src/objects/flame-shield.cpp | 82 ++++++++++++++++++++++++++++++++++++ src/p_mobj.c | 12 +++++- 6 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 src/objects/flame-shield.cpp diff --git a/src/info.c b/src/info.c index f8c30e83a..e0756d795 100644 --- a/src/info.c +++ b/src/info.c @@ -15481,7 +15481,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_FLAMESHIELD -1, // doomednum - S_FLAMESHIELD1, // spawnstate + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/k_kart.c b/src/k_kart.c index 4879bd517..cbb0050b4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -14193,6 +14193,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetTarget(&shield->target, player->mo); S_StartSound(player->mo, sfx_s3k3e); player->curshield = KSHIELD_FLAME; + + Obj_SpawnFlameShieldVisuals(shield); } if (!HOLDING_ITEM && NO_HYUDORO) diff --git a/src/k_objects.h b/src/k_objects.h index a3468cb8e..cbdb189a7 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -457,6 +457,10 @@ boolean Obj_TickBubbleShieldVisual(mobj_t *mobj); void Obj_SpawnLightningShieldVisuals(mobj_t *source); boolean Obj_TickLightningShieldVisual(mobj_t *mobj); +/* Flame Shield */ +void Obj_SpawnFlameShieldVisuals(mobj_t *source); +boolean Obj_TickFlameShieldVisual(mobj_t *mobj); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 1b9b26f0f..d82a2d77c 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -63,6 +63,7 @@ target_sources(SRB2SDL2 PRIVATE bubble-shield.cpp flybot767.c lightning-shield.cpp + flame-shield.cpp ) add_subdirectory(versus) diff --git a/src/objects/flame-shield.cpp b/src/objects/flame-shield.cpp new file mode 100644 index 000000000..bed96c97a --- /dev/null +++ b/src/objects/flame-shield.cpp @@ -0,0 +1,82 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2025 by James Robert Roman +// Copyright (C) 2025 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- + +#include "objects.hpp" + +#include "../tables.h" + +using namespace srb2::objects; + +namespace +{ + +struct Shield : Mobj +{ + void target() = delete; + Mobj* follow() const { return Mobj::target(); } + void follow(Mobj* n) { Mobj::target(n); } + + player_t* player() const { return follow()->player; } + + bool valid() const { return Mobj::valid(follow()) && player(); } +}; + +struct Visual : Mobj +{ + void target() = delete; + Shield* shield() const { return Mobj::target(); } + void shield(Shield* n) { Mobj::target(n); } + + bool valid() const { return Mobj::valid(shield()) && shield()->valid(); } + + static void spawn + ( Shield* shield, + statenum_t state, + int offset) + { + if (!shield->valid()) + return; + + Visual* x = Mobj::spawn(shield->pos(), MT_FLAMESHIELD_VISUAL); + x->scale(5 * shield->follow()->scale() / 4); + x->state(state); + x->shield(shield); + x->linkdraw(shield->follow(), offset); + } + + bool tick() + { + if (!valid()) + { + remove(); + return false; + } + + move_origin(shield()->pos()); + + renderflags = (renderflags & ~RF_DONTDRAW) | + (shield()->state()->num() == S_INVISIBLE ? 0 : RF_DONTDRAW); + + return true; + } +}; + +}; // namespace + +void Obj_SpawnFlameShieldVisuals(mobj_t *shield) +{ + Visual::spawn(static_cast(shield), S_FLMA1, 1); + Visual::spawn(static_cast(shield), S_FLMB1, -1); +} + +boolean Obj_TickFlameShieldVisual(mobj_t *mobj) +{ + return static_cast(mobj)->tick(); +} diff --git a/src/p_mobj.c b/src/p_mobj.c index ea6bb86df..e5b0e9530 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6674,6 +6674,14 @@ static void P_MobjSceneryThink(mobj_t *mobj) } break; } + case MT_FLAMESHIELD_VISUAL: + { + if (!Obj_TickFlameShieldVisual(mobj)) + { + return; + } + break; + } default: if (mobj->fuse) { // Scenery object fuse! Very basic! @@ -8722,8 +8730,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj) else { if (curstate >= S_FLAMESHIELDDASH1 && curstate <= S_FLAMESHIELDDASH12) - P_SetMobjState(mobj, S_FLAMESHIELD1); - mobj->dispoffset = ((curstate - S_FLAMESHIELD1) & 1) ? -1 : 1; + P_SetMobjState(mobj, S_INVISIBLE); + //mobj->dispoffset = ((curstate - S_FLAMESHIELD1) & 1) ? -1 : 1; } mobj->extravalue1 = mobj->target->player->flamedash; From 53871fefc0319d94ea5510f3e3d5769b16c92a49 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 19 May 2025 18:38:29 -0700 Subject: [PATCH 6/6] Make Flame Shield dash effects additive --- src/info.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/info.c b/src/info.c index e0756d795..fb1d9777e 100644 --- a/src/info.c +++ b/src/info.c @@ -2613,29 +2613,29 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 16, {NULL}, 0, 0, S_FLMA1}, // S_FLMA2 {SPR_FLMB, FF_FULLBRIGHT|FF_ANIMATE, 44, {NULL}, 43, 1, S_FLMB1}, // S_FLMB1 - {SPR_FLMD, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH2}, // S_FLAMESHIELDDASH1 - {SPR_FLMD, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH3}, // S_FLAMESHIELDDASH2 - {SPR_FLMD, FF_FULLBRIGHT, 1, {A_FlameShieldPaper}, 0, 2, S_FLAMESHIELDDASH4}, // S_FLAMESHIELDDASH3 - {SPR_FLMD, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH5}, // S_FLAMESHIELDDASH4 - {SPR_FLMD, FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH6}, // S_FLAMESHIELDDASH5 - {SPR_FLMD, FF_FULLBRIGHT, 1, {A_FlameShieldPaper}, 1, 3, S_FLAMESHIELDDASH7}, // S_FLAMESHIELDDASH6 - {SPR_FLMD, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH8}, // S_FLAMESHIELDDASH7 - {SPR_FLMD, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH9}, // S_FLAMESHIELDDASH8 - {SPR_FLMD, FF_FULLBRIGHT, 1, {A_FlameShieldPaper}, 2, 0, S_FLAMESHIELDDASH10}, // S_FLAMESHIELDDASH9 - {SPR_FLMD, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH11}, // S_FLAMESHIELDDASH10 - {SPR_FLMD, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH12}, // S_FLAMESHIELDDASH11 - {SPR_FLMD, FF_FULLBRIGHT, 1, {A_FlameShieldPaper}, 3, 1, S_FLAMESHIELDDASH1}, // S_FLAMESHIELDDASH12 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH2}, // S_FLAMESHIELDDASH1 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH3}, // S_FLAMESHIELDDASH2 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT, 1, {A_FlameShieldPaper}, 0, 2, S_FLAMESHIELDDASH4}, // S_FLAMESHIELDDASH3 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH5}, // S_FLAMESHIELDDASH4 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH6}, // S_FLAMESHIELDDASH5 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT, 1, {A_FlameShieldPaper}, 1, 3, S_FLAMESHIELDDASH7}, // S_FLAMESHIELDDASH6 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH8}, // S_FLAMESHIELDDASH7 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH9}, // S_FLAMESHIELDDASH8 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT, 1, {A_FlameShieldPaper}, 2, 0, S_FLAMESHIELDDASH10}, // S_FLAMESHIELDDASH9 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH11}, // S_FLAMESHIELDDASH10 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_FLAMESHIELDDASH12}, // S_FLAMESHIELDDASH11 + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT, 1, {A_FlameShieldPaper}, 3, 1, S_FLAMESHIELDDASH1}, // S_FLAMESHIELDDASH12 - {SPR_FLMD, FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDDASH2_UNDERLAY - {SPR_FLMD, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDDASH5_UNDERLAY - {SPR_FLMD, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDDASH8_UNDERLAY - {SPR_FLMD, FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDDASH11_UNDERLAY + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|9, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDDASH2_UNDERLAY + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDDASH5_UNDERLAY + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDDASH8_UNDERLAY + {SPR_FLMD, FF_ADD|FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDDASH11_UNDERLAY - {SPR_FLMP, FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDPAPER - {SPR_FLML, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 7, {NULL}, 6, 1, S_NULL}, // S_FLAMESHIELDLINE1 - {SPR_FLML, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|7, 7, {NULL}, 6, 1, S_NULL}, // S_FLAMESHIELDLINE2 - {SPR_FLML, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|14, 7, {NULL}, 6, 1, S_NULL}, // S_FLAMESHIELDLINE3 - {SPR_FLMF, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDFLASH + {SPR_FLMP, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDPAPER + {SPR_FLML, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, 7, {NULL}, 6, 1, S_NULL}, // S_FLAMESHIELDLINE1 + {SPR_FLML, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|7, 7, {NULL}, 6, 1, S_NULL}, // S_FLAMESHIELDLINE2 + {SPR_FLML, FF_ADD|FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|14, 7, {NULL}, 6, 1, S_NULL}, // S_FLAMESHIELDLINE3 + {SPR_FLMF, FF_ADD|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_FLAMESHIELDFLASH {SPR_GTOP, FF_ANIMATE, -1, {NULL}, 5, 1, S_NULL}, // S_GARDENTOP_FLOATING {SPR_GTOP, 0, 1, {NULL}, 5, 1, S_GARDENTOP_SINKING2}, // S_GARDENTOP_SINKING1