Merge branch 'caulking-the-gas-ball' into 'master'

Hardcode Sealed Star objects

See merge request KartKrew/Kart!1792
This commit is contained in:
Oni 2024-01-12 03:02:41 +00:00
commit c23f0a175b
11 changed files with 1721 additions and 2 deletions

View file

@ -303,6 +303,9 @@ actionpointer_t actionpointers[] =
{{A_SpawnItemDebrisCloud}, "A_SPAWNITEMDEBRISCLOUD"},
{{A_RingShooterFace}, "A_RINGSHOOTERFACE"},
{{A_SpawnSneakerPanel}, "A_SPAWNSNEAKERPANEL"},
{{A_MakeSSCandle}, "A_MAKESSCANDLE"},
{{A_HologramRandomTranslucency}, "A_HOLOGRAMRANDOMTRANSLUCENCY"},
{{A_SSChainShatter}, "A_SSCHAINSHATTER"},
{{NULL}, "NONE"},
@ -4948,6 +4951,70 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
// MT_WATERFALLPARTICLESPAWNER
"S_WATERFALLPARTICLE",
// Sealed Stars
// MT_SSCANDLE
"S_SSCANDLE_INIT",
"S_SSCANDLE",
// MT_SSCANDLE_SIDE
"S_SSCANDLE_SIDE",
// MT_SSCANDLE_FLAME
"S_SSCANDLE_FLAME",
// MT_SS_HOLOGRAM
"S_HOLOGRAM_BIRD",
"S_HOLOGRAM_CRAB",
"S_HOLOGRAM_FISH",
"S_HOLOGRAM_SQUID",
// MT_SS_COIN
"S_SS_COIN",
// MT_SS_GOBLET
"S_SS_GOBLET",
// MT_SS_LAMP
"S_SS_LAMP",
// MT_SS_LAMP_BULB
"S_SS_LAMP_BULB",
"S_SS_LAMP_AURA",
// MT_SSWINDOW
"S_SSWINDOW_INIT",
"S_SSWINDOW",
// MT_SSWINDOW_SHINE
"S_SSWINDOW_SHINE",
// MT_SSCHAINSOUND
"S_SSCHAINSOUND",
// MT_SEALEDSTAR_BUMPER
"S_SEALEDSTAR_BUMPER",
"S_SEALEDSTAR_BUMPERHIT",
// MT_SSCHAIN_SPAWNER
"S_SSCHAIN_SPAWNER_SHATTER",
// MT_SSCHAIN
"S_SSCHAIN1",
// MT_GACHATARGET
"S_GACHATARGET",
"S_GACHATARGETSPIN",
"S_GACHATARGETOK",
// MT_CABOTRON
"S_CABOTRON",
// MT_CABOTRONSTAR
"S_CABOTRONSTAR",
// MT_STARSTREAM
"S_STARSTREAM",
};
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
@ -6232,6 +6299,29 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_TRICKBALLOON_YELLOW_POINT",
"MT_WATERFALLPARTICLESPAWNER",
"MT_SSCANDLE",
"MT_SSCANDLE_SIDE",
"MT_SSCANDLE_FLAME",
"MT_SS_HOLOGRAM",
"MT_SS_HOLOGRAM_ROTATOR",
"MT_SS_COIN",
"MT_SS_COIN_CLOUD",
"MT_SS_GOBLET",
"MT_SS_GOBLET_CLOUD",
"MT_SS_LAMP",
"MT_SS_LAMP_BULB",
"MT_SSWINDOW",
"MT_SSWINDOW_SHINE",
"MT_SSCHAINSOUND",
"MT_SLSTMACE",
"MT_SEALEDSTAR_BUMPER",
"MT_SSCHAIN_SPAWNER",
"MT_SSCHAIN",
"MT_GACHATARGET",
"MT_CABOTRON",
"MT_CABOTRONSTAR",
"MT_STARSTREAM",
};
const char *const MOBJFLAG_LIST[] = {

View file

@ -1037,6 +1037,25 @@ char sprnames[NUMSPRITES + 1][5] =
// Waterfall particles
"WTRP",
// Sealed Stars
"SCND",
"SCNF",
"SSBI",
"SSCR",
"SSFI",
"SSSQ",
"SSCO",
"SGOB",
"SSLA",
"SWIN",
"SWIS",
"SBMP",
"SSCH",
"GCTA",
"SENB",
"SENC",
"SEAS",
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
"VIEW",
};
@ -5848,6 +5867,69 @@ state_t states[NUMSTATES] =
// MT_WATERFALLPARTICLESPAWNER
{SPR_WTRP, FF_ANIMATE, 32, {NULL}, 31, 1, S_NULL},
// MT_SSCANDLE
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_SSCANDLE}, // S_SSCANDLE_INIT
{SPR_NULL, 0, -1, {A_MakeSSCandle}, 0, 0, S_SSCANDLE}, // S_SSCANDLE
// MT_SSCANDLE_SIDE
{SPR_SCND, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_SSCANDLE_SIDE}, // S_SSCANDLE_SIDE
// MT_SSCANDLE_FLAME
{SPR_SCNF, FF_ANIMATE|FF_FULLBRIGHT|FF_ADD|FF_RANDOMANIM|0, -1, {NULL}, 15, 4, S_SSCANDLE_FLAME}, // S_SSCANDLE_FLAME
// MT_SS_HOLOGRAM
{SPR_SSBI, FF_PAPERSPRITE|FF_ANIMATE|FF_ADD|0, -1, {A_HologramRandomTranslucency}, 15, 1, S_NULL}, // S_HOLOGRAM_BIRD
{SPR_SSCR, FF_PAPERSPRITE|FF_ANIMATE|FF_ADD|0, -1, {A_HologramRandomTranslucency}, 15, 1, S_NULL}, // S_HOLOGRAM_CRAB
{SPR_SSFI, FF_PAPERSPRITE|FF_ANIMATE|FF_ADD|0, -1, {A_HologramRandomTranslucency}, 15, 1, S_NULL}, // S_HOLOGRAM_FISH
{SPR_SSSQ, FF_PAPERSPRITE|FF_ANIMATE|FF_ADD|0, -1, {A_HologramRandomTranslucency}, 15, 1, S_NULL}, // S_HOLOGRAM_SQUID
// MT_SS_COIN
{SPR_SSCO, 0, 0, {NULL}, 0, 0, S_NULL}, // S_SS_COIN
// MT_SS_GOBLET
{SPR_SGOB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SS_GOBLET
// MT_SS_LAMP
{SPR_SSLA, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SS_LAMP
// MT_SS_LAMP_BULB
{SPR_SSLA, 1|FF_PAPERSPRITE|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_SS_LAMP_BULB
{SPR_SSLA, 3|FF_ANIMATE|FF_FULLBRIGHT|FF_ADD, -1, {NULL}, 1, 1, S_NULL}, // S_SS_LAMP_AURA
// MT_SSWINDOW
{SPR_SWIN, FF_PAPERSPRITE|FF_FULLBRIGHT|FF_TRANS30|0, 1, {A_ChangeAngleRelative}, -90, -90, S_SSWINDOW}, // S_SSWINDOW_INIT
{SPR_SWIN, FF_PAPERSPRITE|FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30|0, -1, {NULL}, 31, 4, S_SSWINDOW}, // S_SSWINDOW
// MT_SSWINDOW_SHINE
{SPR_SWIS, FF_PAPERSPRITE|FF_ANIMATE|FF_FULLBRIGHT|FF_ADD|FF_RANDOMANIM|0, -1, {NULL}, 31, 3, S_SSWINDOW_SHINE}, // S_SSWINDOW_SHINE
// MT_SSCHAINSOUND
{SPR_NULL, 0, 16, {A_PlaySound}, sfx_ssthnk, 1, S_SSCHAINSOUND}, // S_SSCHAINSOUND
// MT_SEALEDSTAR_BUMPER
{SPR_SBMP, 0|FF_FULLBRIGHT, -1, {NULL}, 2, 8, S_SEALEDSTAR_BUMPER}, // S_SEALEDSTAR_BUMPER
{SPR_SBMP, 1|FF_ANIMATE|FF_FULLBRIGHT, 8, {NULL}, 1, 2, S_SEALEDSTAR_BUMPER}, // S_SEALEDSTAR_BUMPERHIT
// MT_SSCHAIN_SPAWNER
{SPR_NULL, 0, 2, {A_SSChainShatter}, 0, 0, S_NULL}, // S_SSCHAIN_SPAWNER_SHATTER
// MT_SSCHAIN
{SPR_SSCH, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SSCHAIN1
// MT_GACHATARGET
{SPR_GCTA, FF_PAPERSPRITE|FF_FULLBRIGHT|0, -1, {NULL}, 0, 0, S_NULL}, // S_GACHATARGET
{SPR_GCTA, FF_PAPERSPRITE|FF_ANIMATE|FF_FULLBRIGHT|0, 12, {NULL}, 3, 4, S_GACHATARGETOK}, // S_GACHATARGETSPIN
{SPR_GCTA, FF_PAPERSPRITE|FF_FULLBRIGHT|5, -1, {NULL}, 0, 0, S_NULL}, // S_GACHATARGETOK
// MT_CABOTRON
{SPR_SENB, 0|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_CABOTRON}, // S_CABOTRON
// MT_CABOTRONSTAR
{SPR_SENC, 0|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_CABOTRONSTAR}, // S_CABOTRONSTAR
// MT_STARSTREAM
{SPR_SEAS, FF_ANIMATE|0, 30, {NULL}, 29, 1, S_NULL}, // S_STARSTREAM
};
mobjinfo_t mobjinfo[NUMMOBJTYPES] =
@ -33553,6 +33635,578 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SSCANDLE
3492, // doomednum
S_SSCANDLE_INIT, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
16*FRACUNIT, // radius
256*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_RUNSPAWNFUNC|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SSCANDLE_SIDE
-1, // doomednum
S_SSCANDLE_SIDE, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
16*FRACUNIT, // radius
256*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOGRAVITY|MF_NOTHINK, // flags
S_NULL // raisestate
},
{ // MT_SSCANDLE_FLAME
-1, // doomednum
S_SSCANDLE_FLAME, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
32*FRACUNIT, // radius
32*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SS_HOLOGRAM
3475, // doomednum
S_HOLOGRAM_CRAB, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
3, // 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
0, // speed
128*FRACUNIT, // radius
256*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SS_HOLOGRAM_ROTATOR
3476, // doomednum
S_INVISIBLE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
0, // radius
0, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SS_COIN
-1, // doomednum
S_SS_COIN, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
18*FRACUNIT, // radius
37*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SS_COIN_CLOUD
3474, // doomednum
S_INVISIBLE, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
0, // radius
0, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SS_GOBLET
-1, // doomednum
S_SS_GOBLET, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
20*FRACUNIT, // radius
64*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SS_GOBLET_CLOUD
3478, // doomednum
S_INVISIBLE, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
0, // radius
0, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SS_LAMP
3477, // doomednum
S_SS_LAMP, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
12*FRACUNIT, // radius
369*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DRAWFROMFARAWAY, // flags
S_NULL // raisestate
},
{ // MT_SS_LAMP_BULB
-1, // doomednum
S_SS_LAMP_BULB, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
16*FRACUNIT, // radius
85*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DRAWFROMFARAWAY, // flags
S_NULL // raisestate
},
{ // MT_SSWINDOW
3493, // doomednum
S_SSWINDOW_INIT, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
192*FRACUNIT, // radius
512*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_RUNSPAWNFUNC|MF_NOGRAVITY|MF_NOCLIP, // flags
S_NULL // raisestate
},
{ // MT_SSWINDOW_SHINE
-1, // doomednum
S_SSWINDOW_SHINE, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
192*FRACUNIT, // radius
512*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOGRAVITY|MF_NOCLIP, // flags
S_NULL // raisestate
},
{ // MT_SSCHAINSOUND
3494, // doomednum
S_SSCHAINSOUND, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
1*FRACUNIT, // radius
1*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_NOCLIP, // flags
S_NULL // raisestate
},
{ // MT_SLSTMACE
-1, // doomednum
S_INVISIBLE, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
1*FRACUNIT, // radius
1*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
0, // flags
S_NULL // raisestate
},
{ // MT_SEALEDSTAR_BUMPER
2461, // doomednum
S_SEALEDSTAR_BUMPER, // spawnstate
1, // spawnhealth
S_SEALEDSTAR_BUMPERHIT, // seestate
sfx_None, // seesound
0, // 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_ssbmpr, // deathsound
0, // speed
24*FRACUNIT, // radius
32*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_SPECIAL|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SSCHAIN_SPAWNER
3479, // doomednum
S_INVISIBLE, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
1*FRACUNIT, // radius
1*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_SSCHAIN
-1, // doomednum
S_SSCHAIN1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
1*FRACUNIT, // radius
1*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOSQUISH, // flags
S_NULL // raisestate
},
{ // MT_GACHATARGET
3739, // doomednum
S_GACHATARGET, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_GACHATARGETSPIN, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
32*4*FRACUNIT,// radius
64*4*FRACUNIT,// height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_ENEMY|MF_SHOOTABLE|MF_NOHITLAGFORME, // flags
S_NULL // raisestate
},
{ // MT_CABOTRON
3738, // doomednum
S_CABOTRON, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
MT_CABOTRONSTAR, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
2, // speed
32*FRACUNIT, // radius
64*FRACUNIT, // height
0, // dispoffset
8*FRACUNIT, // mass
5, // damage
sfx_None, // activesound
MF_SPECIAL|MF_ENEMY|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_CABOTRONSTAR
-1, // doomednum
S_CABOTRONSTAR, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
32*FRACUNIT, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
4*FRACUNIT, // speed
26*FRACUNIT, // radius
52*FRACUNIT, // height
0, // dispoffset
0, // mass
8, // damage
sfx_None, // activesound
MF_PAIN|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_STARSTREAM
-1, // doomednum
S_STARSTREAM, // spawnstate
10000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // 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
0, // speed
4*FRACUNIT, // radius
4*FRACUNIT, // height
0, // dispoffset
0, // mass
8, // damage
sfx_None, // activesound
MF_SCENERY|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
};

View file

@ -297,6 +297,9 @@ enum actionnum
A_RINGSHOOTERFACE,
A_SPAWNSNEAKERPANEL,
A_BLENDEYEPUYOHACK,
A_MAKESSCANDLE,
A_HOLOGRAMRANDOMTRANSLUCENCY,
A_SSCHAINSHATTER,
NUMACTIONS
};
@ -574,6 +577,9 @@ void A_SpawnItemDebrisCloud();
void A_RingShooterFace();
void A_SpawnSneakerPanel();
void A_BlendEyePuyoHack();
void A_MakeSSCandle();
void A_HologramRandomTranslucency();
void A_SSChainShatter();
extern boolean actionsoverridden[NUMACTIONS];
@ -1591,6 +1597,25 @@ typedef enum sprite
// Waterfall particles
SPR_WTRP,
// Sealed Stars
SPR_SCND, // Candle
SPR_SCNF, // Candle Flame
SPR_SSBI, // Hologram Bird
SPR_SSCR, // Hologram Crab
SPR_SSFI, // Hologram Fish
SPR_SSSQ, // Hologram Squid
SPR_SSCO, // Coin
SPR_SGOB, // Goblet
SPR_SSLA, // Lamp
SPR_SWIN, // Window
SPR_SWIS, // Window Shine
SPR_SBMP, // Bumper
SPR_SSCH, // Chain
SPR_GCTA, // Gachatarget
SPR_SENB, // Cabotron
SPR_SENC, // Cabotron
SPR_SEAS, // Starstream
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
SPR_VIEW,
@ -6273,6 +6298,70 @@ typedef enum state
// MT_WATERFALLPARTICLESPAWNER
S_WATERFALLPARTICLE,
// Sealed Stars
// MT_SSCANDLE
S_SSCANDLE_INIT,
S_SSCANDLE,
// MT_SSCANDLE_SIDE
S_SSCANDLE_SIDE,
// MT_SSCANDLE_FLAME
S_SSCANDLE_FLAME,
// MT_SS_HOLOGRAM
S_HOLOGRAM_BIRD,
S_HOLOGRAM_CRAB,
S_HOLOGRAM_FISH,
S_HOLOGRAM_SQUID,
// MT_SS_COIN
S_SS_COIN,
// MT_SS_GOBLET
S_SS_GOBLET,
// MT_SS_LAMP
S_SS_LAMP,
// MT_SS_LAMP_BULB
S_SS_LAMP_BULB,
S_SS_LAMP_AURA,
// MT_SSWINDOW
S_SSWINDOW_INIT,
S_SSWINDOW,
// MT_SSWINDOW_SHINE
S_SSWINDOW_SHINE,
// MT_SSCHAINSOUND
S_SSCHAINSOUND,
// MT_SEALEDSTAR_BUMPER
S_SEALEDSTAR_BUMPER,
S_SEALEDSTAR_BUMPERHIT,
// MT_SSCHAIN_SPAWNER
S_SSCHAIN_SPAWNER_SHATTER,
// MT_SSCHAIN
S_SSCHAIN1,
// MT_GACHATARGET
S_GACHATARGET,
S_GACHATARGETSPIN,
S_GACHATARGETOK,
// MT_CABOTRON
S_CABOTRON,
// MT_CABOTRONSTAR
S_CABOTRONSTAR,
// MT_STARSTREAM
S_STARSTREAM,
S_FIRSTFREESLOT,
S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1,
NUMSTATES
@ -7579,6 +7668,29 @@ typedef enum mobj_type
MT_WATERFALLPARTICLESPAWNER,
MT_SSCANDLE,
MT_SSCANDLE_SIDE,
MT_SSCANDLE_FLAME,
MT_SS_HOLOGRAM,
MT_SS_HOLOGRAM_ROTATOR,
MT_SS_COIN,
MT_SS_COIN_CLOUD,
MT_SS_GOBLET,
MT_SS_GOBLET_CLOUD,
MT_SS_LAMP,
MT_SS_LAMP_BULB,
MT_SSWINDOW,
MT_SSWINDOW_SHINE,
MT_SSCHAINSOUND,
MT_SLSTMACE,
MT_SEALEDSTAR_BUMPER,
MT_SSCHAIN_SPAWNER,
MT_SSCHAIN,
MT_GACHATARGET,
MT_CABOTRON,
MT_CABOTRONSTAR,
MT_STARSTREAM,
MT_FIRSTFREESLOT,
MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1,
NUMMOBJTYPES

View file

@ -369,6 +369,28 @@ void Obj_BulbTouched(mobj_t *special, mobj_t *toucher);
/* Waterfall Particles Spawner */
void Obj_WaterfallParticleThink(mobj_t *mo);
/* Sealed Star objects */
void Obj_SSCandleMobjThink(mobj_t* mo);
void Obj_SSHologramRotatorMapThingSpawn(mobj_t* mo, mapthing_t* mt);
void Obj_SSHologramRotatorMobjThink(mobj_t* mo);
void Obj_SSHologramMobjSpawn(mobj_t* mo);
void Obj_SSHologramMobjFuse(mobj_t* mo);
void Obj_SSHologramMapThingSpawn(mobj_t* mo, mapthing_t* mt);
void Obj_SSCoinCloudMapThingSpawn(mobj_t* mo, mapthing_t* mt);
void Obj_SSCoinMobjThink(mobj_t* mo);
void Obj_SSGobletCloudMapThingSpawn(mobj_t* mo, mapthing_t* mt);
void Obj_SSGobletMobjThink(mobj_t* mo);
void Obj_SSLampMapThingSpawn(mobj_t* mo, mapthing_t* mt);
void Obj_SSWindowMapThingSpawn(mobj_t* mo, mapthing_t* mt);
void Obj_SLSTMaceMobjThink(mobj_t* mo);
void Obj_SSBumperTouchSpecial(mobj_t* special, mobj_t* toucher);
void Obj_SSBumperMobjSpawn(mobj_t* mo);
void Obj_SSChainMobjThink(mobj_t* mo);
void Obj_SSGachaTargetMobjSpawn(mobj_t* mo);
void Obj_SSCabotronMobjSpawn(mobj_t* mo);
void Obj_SSCabotronMobjThink(mobj_t* mo);
void Obj_SSCabotronStarMobjThink(mobj_t* mo);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -52,6 +52,7 @@ target_sources(SRB2SDL2 PRIVATE
trick-balloon.c
cloud.c
waterfall-particle.c
sealed-star.c
)
add_subdirectory(versus)

667
src/objects/sealed-star.c Normal file
View file

@ -0,0 +1,667 @@
// DR. ROBOTNIK'S RING RACERS
//-------------------------------
// Copyright (C) 2024 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.
//-----------------------------------------------------------------------------
/// \brief Sealed Star objects
#include <string.h>
#include "../info.h"
#include "../doomdef.h"
#include "../g_game.h"
#include "../p_local.h"
#include "../m_fixed.h"
#include "../m_random.h"
#include "../k_kart.h"
#include "../k_objects.h"
#include "../r_main.h"
#include "../s_sound.h"
static const INT32 kMinTranslucency = 0;
static const INT32 kMaxTranslucency = 10;
void Obj_SSCandleMobjThink(mobj_t* mo)
{
mo->extravalue1 = (mo->extravalue1 + 3) % 360;
mo->z += FSIN(mo->extravalue1 * ANG1) / 4;
if (mo->tracer)
{
mo->tracer->z = mo->z + (256*FRACUNIT);
}
}
void Obj_SSHologramRotatorMapThingSpawn(mobj_t* mo, mapthing_t* mt)
{
INT32 numStates = 0;
statenum_t mystates[32] = {0};
char stringarg[256];
char *token;
int i;
INT32 speed = 8;
INT32 radius = 256;
INT32 amplitude = mt->thing_args[2];
INT32 frequency = mt->thing_args[3];
angle_t angDiff;
mobj_t* part;
fixed_t circumference;
// This is probably dangerously unsafe but what code written in C isn't
// Christ, parsing strings in C is heinous
// strtok is a nightmare so let's try to avoid that
if (mt->thing_stringargs[0] == NULL)
{
CONS_Alert(CONS_WARNING, "MT_HOLOGRAM_ROTATOR %d: stringarg 0 is NULL\n", mt->tid);
return;
}
memset(stringarg, 0, sizeof(stringarg));
strlcpy(stringarg, mt->thing_stringargs[0], sizeof(stringarg));
for (i = 0; i < (int)(sizeof(stringarg)); i++)
{
if (stringarg[i] == ' ' || stringarg[i] == ',')
{
stringarg[i] = 0;
}
}
stringarg[sizeof(stringarg) - 1] = 0;
for (token = stringarg; token < stringarg + sizeof(stringarg) && numStates < 32; )
{
char *next = token + strlen(token) + 1;
if (stricmp(token, "bird") == 0)
{
mystates[numStates] = S_HOLOGRAM_BIRD;
numStates += 1;
}
else if (stricmp(token, "fish") == 0)
{
mystates[numStates] = S_HOLOGRAM_FISH;
numStates += 1;
}
else if (stricmp(token, "crab") == 0)
{
mystates[numStates] = S_HOLOGRAM_CRAB;
numStates += 1;
}
else if (stricmp(token, "squid") == 0)
{
mystates[numStates] = S_HOLOGRAM_SQUID;
numStates += 1;
}
token = next;
}
if (numStates == 0)
{
CONS_Alert(CONS_WARNING, "MT_HOLOGRAM_ROTATOR %d: stringarg 0 consists exclusively of unrecognised creatures\n", mt->tid);
return;
}
if (mt->thing_args[0])
{
speed = mt->thing_args[0];
}
if (mt->thing_args[1])
{
radius = mt->thing_args[1];
}
// adjust for quarter-scale default
radius *= 4;
amplitude *= 2;
angDiff = FixedAngle(360 * FRACUNIT/numStates);
part = mo;
circumference = 2 * M_PI_FIXED * radius;
mo->cusval = abs(speed * mo->scale);
mo->movedir = FixedAngle(FixedDiv(360 * speed * FRACUNIT, circumference));
mo->movefactor = radius * mo->scale;
if (amplitude > 0 && frequency > 0)
{
mo->extravalue1 = amplitude * mo->scale;
mo->extravalue2 = frequency * ANG1 / 2;
}
else
{
mo->extravalue1 = 0;
mo->extravalue2 = 0;
}
for (i = 0; i < numStates; i++)
{
statenum_t thisstate = mystates[i];
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SS_HOLOGRAM));
P_SetTarget(&part->hnext->hprev, part);
part = part->hnext;
P_SetTarget(&part->target, mo);
P_SetMobjState(part, thisstate);
part->angle = angDiff * i;
if (speed < 0)
{
part->renderflags ^= RF_HORIZONTALFLIP;
}
}
}
void Obj_SSHologramRotatorMobjThink(mobj_t* mo)
{
mobj_t* part = mo;
while (part->hnext)
{
fixed_t oldZ, z;
part = part->hnext;
oldZ = part->z;
if (mo->extravalue1)
{
z = mo->z + mo->extravalue1 + FixedMul(mo->extravalue1, FSIN(mo->extravalue2 * (part->extravalue2 + leveltime)));
}
else
{
z = oldZ;
}
part->angle += mo->movedir;
P_MoveOrigin(
part,
mo->x + FixedMul(mo->movefactor, FCOS(part->angle - ANGLE_90)),
mo->y + FixedMul(mo->movefactor, FSIN(part->angle - ANGLE_90)),
z
);
part->rollangle = R_PointToAngle2(0, 0, mo->cusval, z - oldZ);
}
}
void Obj_SSHologramMobjSpawn(mobj_t* mo)
{
mo->fuse = mo->reactiontime;
mo->threshold = -1 + P_RandomKey(PR_UNDEFINED, 2) * 2;
mo->extravalue2 = P_RandomFixed(PR_UNDEFINED);
}
void Obj_SSHologramMapThingSpawn(mobj_t* mo, mapthing_t* mt)
{
char* stringarg0 = mt->thing_stringargs[0];
if (stringarg0 == NULL)
{
P_SetMobjState(mo, S_HOLOGRAM_CRAB);
}
else if (stricmp(stringarg0, "bird"))
{
P_SetMobjState(mo, S_HOLOGRAM_BIRD);
}
else if (stricmp(stringarg0, "crab") == 0)
{
P_SetMobjState(mo, S_HOLOGRAM_CRAB);
}
else if (stricmp(stringarg0, "fish") == 0)
{
P_SetMobjState(mo, S_HOLOGRAM_FISH);
}
else if (stricmp(stringarg0, "squid") == 0)
{
P_SetMobjState(mo, S_HOLOGRAM_SQUID);
}
if (mt->thing_args[0])
{
mo->renderflags ^= RF_HORIZONTALFLIP;
}
}
void Obj_SSHologramMobjFuse(mobj_t* mo)
{
INT32 trans = (mo->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
if (trans >= kMaxTranslucency)
{
mo->threshold = -1;
}
else if (trans <= kMinTranslucency)
{
mo->threshold = 1;
}
trans += mo->threshold;
mo->frame = (mo->frame & ~FF_TRANSMASK) | (trans << FF_TRANSSHIFT);
if (trans >= kMaxTranslucency)
{
mo->fuse = 24;
}
else
{
mo->fuse = mo->reactiontime;
}
}
static struct {
INT32 t;
INT32 x;
INT32 y;
INT32 z;
INT32 w;
INT32 xx;
INT32 yy;
INT32 zz;
INT32 ww;
} srng_state = {0, 5197528, 3154710, 9406548, 1028369, 0, 0, 0, 0};
static void set_srng_seed(INT32 seed)
{
srng_state.t = seed;
srng_state.xx = srng_state.x;
srng_state.yy = srng_state.y;
srng_state.zz = srng_state.z;
srng_state.ww = srng_state.w;
}
static INT32 srng_random(void)
{
srng_state.xx = srng_state.yy;
srng_state.yy = srng_state.zz;
srng_state.zz = srng_state.ww;
srng_state.ww = srng_state.ww ^ (srng_state.ww >> 19) ^ srng_state.t ^ (srng_state.t >> 8);
srng_state.t = srng_state.xx ^ (srng_state.xx << 11);
return srng_state.ww;
}
static INT32 srng_RandomRange(INT32 a, INT32 b)
{
return a + abs(srng_random() % (b - a + 1));
}
static fixed_t srng_RandomFixed(void)
{
return (fixed_t)(srng_RandomRange(0, FRACUNIT));
}
static boolean srng_RandomChance(INT32 chance)
{
return srng_RandomFixed() < chance;
}
// spinning-related values
#define COIN_FRAMES (4) // number of frames the coin has
#define MIN_SPIN_TICS (3) // fastest speed with which a coin can animate
#define MAX_SPIN_TICS (10) // slowest speed with which a coin can animate
// spawning-related values
#define SPAWNS_PER_MAPTHINGS (10) // number of coins to spawn per spawner
#define COIN_SCALE (2*FRACUNIT) // upscales coins by this factor
#define SPAWN_RANGE (256*FRACUNIT*4) // cubed range over which coins should spawn
#define MIN_SPACING (64*FRACUNIT*4) // minimum spherical space between each coin
// IMPORTANT not to make the spacing too large relative to the spawn range, or spawn attempts could potentially escalate and impact load times or even cause a softlock
// eidolon hardcoder note: this should probably have been implemented
// with a statistical distribution instead of a linear search,
// but this was hardcoded to copy the exact behavior of the Lua
static boolean cloud_CheckDistribution(mobj_t **coins, INT32 coin_count, fixed_t x, fixed_t y, fixed_t z, fixed_t scale)
{
fixed_t spacing = FixedMul(MIN_SPACING, scale);
int i;
x = FixedMul(x, scale);
y = FixedMul(y, scale);
z = FixedMul(z, scale);
for (i = 0; i < coin_count; i++)
{
mobj_t *coin = coins[i];
if (FixedHypot(FixedHypot(coin->x - x, coin->y - y), coin->z - z) < spacing)
{
return false;
}
}
return true;
}
static void CoinCloudSpawn(mobj_t *mo, INT32 seed, mobjtype_t ty)
{
fixed_t x, y, z;
mobj_t *coins[SPAWNS_PER_MAPTHINGS];
mobj_t *coin;
int i;
set_srng_seed(seed);
for (i = 0; i < SPAWNS_PER_MAPTHINGS; i++)
{
// as mentioned... this is a really goofy way to implement a statistical distribution
do {
x = FixedMul(SPAWN_RANGE, srng_RandomFixed()) - (SPAWN_RANGE >> 1);
y = FixedMul(SPAWN_RANGE, srng_RandomFixed()) - (SPAWN_RANGE >> 1);
z = FixedMul(SPAWN_RANGE, srng_RandomFixed());
} while (!cloud_CheckDistribution(coins, i, x, y, z, mo->scale));
coin = P_SpawnMobjFromMobj(mo, x, y, z, ty);
coin->scale = coin->destscale = FixedMul(coin->scale, COIN_SCALE);
// initial angle & frame
coin->angle = FixedAngle(360 * srng_RandomFixed());
coin->frame = (coin->frame & ~FF_FRAMEMASK) | srng_RandomRange(0, COIN_FRAMES - 1);
// random animation speed
coin->extravalue1 = srng_RandomRange(MIN_SPIN_TICS, MAX_SPIN_TICS);
coin->extravalue2 = coin->extravalue1;
coins[i] = coin;
}
}
void Obj_SSCoinCloudMapThingSpawn(mobj_t* mo, mapthing_t* mt)
{
CoinCloudSpawn(mo, mt->thing_args[0], MT_SS_COIN);
}
void Obj_SSCoinMobjThink(mobj_t* mo)
{
mo->extravalue2 -= 1;
if (mo->extravalue2 <= 0)
{
mo->extravalue2 = mo->extravalue1;
mo->frame = (mo->frame & ~FF_FRAMEMASK) | ((mo->frame + 1) % COIN_FRAMES);
}
}
// spinning-related values
#define GOBLET_FRAMES (8) // number of frames the goblet has
#define MIN_VERTICAL_SPIN_TICS (3) // fastest speed with which a goblet can animate (frame)
#define MAX_VERTICAL_SPIN_TICS (10) // slowest speed with which a goblet can animate (frame)
#define MIN_HORIZONTAL_SPIN_SPEED (ANG1 * 1) // slowest speed with which a goblet can rotate (angle)
#define MAX_HORIZONTAL_SPIN_SPEED (ANG1 * 3) // fastest speed with which a goblet can rotate (angle)
// spawning-related values
#define GOBLET_SPAWNS_PER_MAPTHING (5) // number of goblets to spawn per spawner
#define GOBLET_SCALE (2*FRACUNIT) // upscales goblets by this factor
#define GOBLET_SPAWN_RANGE (256*FRACUNIT*4) // cubed range over which goblets should spawn
#define GOBLET_MIN_SPACING (64*FRACUNIT*4) // minimum spherical space between each goblet
// IMPORTANT not to make the spacing too large relative to the spawn range, or spawn attempts could potentially escalate and impact load times or even cause a softlock
#define GOBLET_SEED_OFFSET (1267491679) // I'm setting a garbage seed offset here so that seed 0 clouds are markedly different to their coin counterparts
static void GobletCloudSpawn(mobj_t *mo, INT32 seed, mobjtype_t ty)
{
fixed_t x, y, z;
mobj_t *coins[GOBLET_SPAWNS_PER_MAPTHING];
mobj_t *coin;
int i;
set_srng_seed(seed + GOBLET_SEED_OFFSET);
for (i = 0; i < GOBLET_SPAWNS_PER_MAPTHING; i++)
{
// as mentioned... this is a really goofy way to implement a statistical distribution
do {
x = FixedMul(GOBLET_SPAWN_RANGE, srng_RandomFixed()) - (GOBLET_SPAWN_RANGE >> 1);
y = FixedMul(GOBLET_SPAWN_RANGE, srng_RandomFixed()) - (GOBLET_SPAWN_RANGE >> 1);
z = FixedMul(GOBLET_SPAWN_RANGE, srng_RandomFixed());
} while (!cloud_CheckDistribution(coins, i, x, y, z, mo->scale));
coin = P_SpawnMobjFromMobj(mo, x, y, z, ty);
coin->scale = coin->destscale = FixedMul(coin->scale, GOBLET_SCALE);
// initial angle & frame
coin->angle = FixedAngle(360 * srng_RandomFixed());
coin->frame = (coin->frame & ~FF_FRAMEMASK) | srng_RandomRange(0, GOBLET_FRAMES - 1);
// random animation speed
coin->extravalue1 = srng_RandomRange(MIN_VERTICAL_SPIN_TICS, MAX_VERTICAL_SPIN_TICS);
coin->extravalue2 = coin->extravalue1;
// random angle speed
coin->movedir = MIN_HORIZONTAL_SPIN_SPEED + FixedMul(srng_RandomFixed(), MAX_HORIZONTAL_SPIN_SPEED - MIN_HORIZONTAL_SPIN_SPEED);
if (srng_RandomChance(FRACUNIT/2))
{
coin->movedir = -coin->movedir;
}
coins[i] = coin;
}
}
void Obj_SSGobletCloudMapThingSpawn(mobj_t* mo, mapthing_t* mt)
{
GobletCloudSpawn(mo, mt->thing_args[0], MT_SS_GOBLET);
}
void Obj_SSGobletMobjThink(mobj_t* mo)
{
mo->angle += mo->movedir;
mo->extravalue2 -= 1;
if (mo->extravalue2 <= 0)
{
mo->extravalue2 = mo->extravalue1;
mo->frame = (mo->frame & ~FF_FRAMEMASK) | ((mo->frame + 1) % GOBLET_FRAMES);
}
}
#define LAMP_SCALE (4 * FRACUNIT)
#define BULB_HORIZONTAL_OFFSET (124 * FRACUNIT)
#define BULB_VERTICAL_OFFSET (243 * FRACUNIT)
void Obj_SSLampMapThingSpawn(mobj_t* mo, mapthing_t* mt)
{
int i;
angle_t angle = FixedAngle(mt->angle * FRACUNIT);
fixed_t bulbX = FixedMul(BULB_HORIZONTAL_OFFSET, FCOS(angle));
fixed_t bulbY = FixedMul(BULB_HORIZONTAL_OFFSET, FSIN(angle));
mobj_t *core, *part;
mo->scale = mo->destscale = FixedMul(mo->scale, LAMP_SCALE);
// INVISIBLE (BUT RENDERERED) CORE
// we need this because linkdrawing to a papersprite results in all linked mobjs becoming invisible when the papersprite is viewed parallel to its angle
core = P_SpawnMobjFromMobj(mo, bulbX, bulbY, BULB_VERTICAL_OFFSET, MT_SS_LAMP_BULB);
P_SetTarget(&core->tracer, mo);
P_SetMobjState(core, S_SHADOW);
// parallel bulb
part = P_SpawnMobjFromMobj(core, 0, 0, 0, MT_SS_LAMP_BULB);
part->angle = angle;
part->flags2 |= MF2_LINKDRAW;
P_SetTarget(&part->tracer, core);
// perpendicular bulb (as 2 minecraft cross parts)
angle += ANGLE_90;
bulbX = FixedMul(core->info->radius, FCOS(angle));
bulbY = FixedMul(core->info->radius, FSIN(angle));
part = core;
for (i = 0; i < 1; i++)
{
P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(core, bulbX, bulbY, 0, MT_SS_LAMP_BULB));
P_SetTarget(&part->hnext->hprev, part);
part = part->hnext;
part->angle = angle;
part->frame = (part->frame & ~FF_FRAMEMASK) | 2;
part->flags2 |= MF2_LINKDRAW;
P_SetTarget(&part->tracer, core);
part->dispoffset = 1;
angle += ANGLE_180;
bulbX = -bulbX;
bulbY = -bulbY;
}
// aura
part = P_SpawnMobjFromMobj(core, 0, 0, 0, MT_SS_LAMP_BULB);
P_SetMobjState(part, S_SS_LAMP_AURA);
part->dispoffset -= 1;
}
void Obj_SSWindowMapThingSpawn(mobj_t* mo, mapthing_t* mt)
{
angle_t angle;
fixed_t co, si, x, y, xofs, yofs;
mobj_t *shinel, *shinem, *shiner;
mo->scale = mo->destscale = FRACUNIT;
angle = FixedAngle(mt->angle * FRACUNIT);
co = FCOS(angle);
si = FSIN(angle);
x = 192 * co;
y = 192 * si;
xofs = 128 * si;
yofs = -128 * co;
shinel = P_SpawnMobjFromMobj(mo, x + xofs, y + yofs, 0, MT_SSWINDOW_SHINE);
shinem = P_SpawnMobjFromMobj(mo, x, y, 64*FRACUNIT, MT_SSWINDOW_SHINE);
shiner = P_SpawnMobjFromMobj(mo, x - xofs, y - yofs, 0, MT_SSWINDOW_SHINE);
shinel->angle = angle;
shinem->angle = angle;
shiner->angle = angle;
shinel->scale = mo->destscale = FRACUNIT;
shinem->scale = mo->destscale = FRACUNIT;
shiner->scale = mo->destscale = FRACUNIT;
}
void Obj_SLSTMaceMobjThink(mobj_t* mo)
{
if (leveltime % 2 == 0)
{
var1 = 9;
var2 = 0;
A_GhostMe(mo);
}
}
#define BUMPER_STRENGTH (56)
void Obj_SSBumperTouchSpecial(mobj_t* special, mobj_t* toucher)
{
angle_t hang;
angle_t vang;
fixed_t str;
int i;
hang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y);
vang = 0;
if (P_IsObjectOnGround(toucher) == false)
{
vang = R_PointToAngle2(
FixedHypot(special->x, special->y), special->z + (special->height >> 1),
FixedHypot(toucher->x, toucher->y), toucher->z + (toucher->height >> 1)
);
}
str = (BUMPER_STRENGTH * special->scale) >> 1;
toucher->momx = FixedMul(FixedMul(str, FCOS(hang)), abs(FCOS(vang)));
toucher->momy = FixedMul(FixedMul(str, FSIN(hang)), abs(FCOS(vang)));
toucher->momz = FixedMul(str, FSIN(vang));
if (toucher->player)
{
if (toucher->player->tiregrease == 0)
{
for (i = 0; i < 2; i++)
{
mobj_t *grease = P_SpawnMobjFromMobj(toucher, 0, 0, 0, MT_TIREGREASE);
P_SetTarget(&grease->target, toucher);
grease->angle = toucher->angle;
grease->extravalue1 = i;
}
}
if (toucher->player->tiregrease < 2*TICRATE) // greasetics
{
toucher->player->tiregrease = 2*TICRATE;
}
}
if (special->state != &states[special->info->seestate])
{
S_StartSound(special, special->info->deathsound);
P_SetMobjState(special, special->info->seestate);
}
}
void Obj_SSBumperMobjSpawn(mobj_t* mo)
{
mo->shadowscale = FRACUNIT;
mo->destscale <<= 1;
P_SetScale(mo, mo->destscale);
}
void Obj_SSChainMobjThink(mobj_t* mo)
{
mo->angle += ANGLE_22h;
if (mo->momx == 0 && P_IsObjectOnGround(mo))
{
P_RemoveMobj(mo);
}
}
void Obj_SSGachaTargetMobjSpawn(mobj_t* mo)
{
mo->scale *= 4;
mo->destscale = mo->scale;
}
void Obj_SSCabotronMobjSpawn(mobj_t* mo)
{
int i;
mobj_t *ball;
for (i = 0; i < 4; i++)
{
ball = P_SpawnMobj(mo->x, mo->y, mo->z, MT_CABOTRONSTAR);
ball->destscale = mo->scale;
P_SetScale(ball, mo->scale);
P_SetTarget(&ball->target, mo);
ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, 5<<FRACBITS), 360<<FRACBITS));
ball->threshold = ball->radius + mo->radius + FixedMul(11*FRACUNIT, ball->scale);
}
mo->scale *= 2;
mo->destscale = mo->scale;
}
void Obj_SSCabotronMobjThink(mobj_t* mo)
{
angle_t xdir = FSIN(mo->angle - ANGLE_90);
angle_t ydir = FCOS(mo->angle + ANGLE_90);
boolean didMove;
didMove = P_TryMove(mo, mo->x - (xdir * mo->info->speed), mo->y - (ydir * mo->info->speed), false, NULL);
if (!didMove)
{
// --print("Flipping sawblade")
mo->angle += ANGLE_180;
}
}
void Obj_SSCabotronStarMobjThink(mobj_t* mo)
{
if (mo->target)
{
// "but ang just call the action in the soc :))))"
var1 = 0;
var2 = 0;
A_UnidusBall(mo);
// how about no because for some reason it will call the func ONCE and never again in its pitiful aimless life
// and let's just hack FF_ANIMATE too shall we; since var1 is being used to make sure the fucking balls don't fly off the handle which means frame anims can't be handled by the soc
// this game is popsicle sticks and i am out of glue.
}
}

View file

@ -329,6 +329,9 @@ void A_SpawnItemDebrisCloud(mobj_t *actor);
void A_RingShooterFace(mobj_t *actor);
void A_SpawnSneakerPanel(mobj_t *actor);
void A_BlendEyePuyoHack(mobj_t *actor);
void A_MakeSSCandle(mobj_t *actor);
void A_HologramRandomTranslucency(mobj_t *actor);
void A_SSChainShatter(mobj_t *actor);
//for p_enemy.c
@ -3819,7 +3822,7 @@ void A_AttractChase(mobj_t *actor)
// Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
actor->target->player->ringboost += K_GetKartRingPower(actor->target->player, true) + 3;
S_ReducedVFXSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume, NULL);
actor->target->player->ringvolume -= RINGVOLUMEUSEPENALTY;
@ -13801,3 +13804,56 @@ void A_BlendEyePuyoHack(mobj_t *actor)
actor->frame = 7;
}
}
void A_MakeSSCandle(mobj_t* actor)
{
int i;
fixed_t dist = ((4 * actor->scale * 6) * 4) + (7 * FRACUNIT) / 2;
// Flame
mobj_t* fire = P_SpawnMobjFromMobj(actor, 0, 0, (256 * FRACUNIT) * 4, MT_SSCANDLE_FLAME);
fire->scale = fire->destscale = FRACUNIT;
P_SetTarget(&actor->tracer, fire);
// Sides
for (i = 0; i < 5; i++)
{
fixed_t a = FixedAngle(60 * FRACUNIT) * i;
fixed_t offsetx = actor->x + FixedMul(dist, FCOS(a));
fixed_t offsety = actor->y + FixedMul(dist, FSIN(a));
mobj_t* side = P_SpawnMobj(offsetx, offsety, actor->z, MT_SSCANDLE_SIDE);
side->angle = a + FixedAngle(90 * FRACUNIT);
side->scale = side->destscale = FRACUNIT;
}
}
void A_HologramRandomTranslucency(mobj_t* actor)
{
actor->frame = (actor->frame & ~FF_TRANSMASK) | (P_RandomRange(PR_UNDEFINED, 0, 10) << FF_TRANSSHIFT);
}
static void A_SSChainShatter_link(mobj_t* actor, angle_t angle)
{
mobj_t *x;
x = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_SSCHAIN);
P_InstaThrust(x, angle, 20 * mapobjectscale);
x->momx = 10 * mapobjectscale * P_MobjFlip(x);
}
void A_SSChainShatter(mobj_t* actor)
{
angle_t angle = P_RandomKey(PR_UNDEFINED, 360) * ANG1;
actor->scale *= 4;
A_SSChainShatter_link(actor, angle);
A_SSChainShatter_link(actor, angle + ANGLE_180);
S_StartSound(NULL, sfx_chcrun);
actor->fuse = 1;
}

View file

@ -1031,6 +1031,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
Obj_TrickBalloonTouchSpecial(special, toucher);
return;
case MT_SEALEDSTAR_BUMPER:
Obj_SSBumperTouchSpecial(special, toucher);
return;
default: // SOC or script pickup
P_SetTarget(&special->target, toucher);
break;

View file

@ -6933,6 +6933,38 @@ static void P_MobjSceneryThink(mobj_t *mobj)
Obj_EMZRainGenerator(mobj);
return;
}
case MT_SSCANDLE:
{
Obj_SSCandleMobjThink(mobj);
return;
}
case MT_SS_HOLOGRAM_ROTATOR:
{
Obj_SSHologramRotatorMobjThink(mobj);
return;
}
case MT_SS_HOLOGRAM:
{
if (mobj->fuse)
{
mobj->fuse--;
}
if (!mobj->fuse)
{
Obj_SSHologramMobjFuse(mobj);
}
return;
}
case MT_SS_COIN:
{
Obj_SSCoinMobjThink(mobj);
return;
}
case MT_SS_GOBLET:
{
Obj_SSGobletMobjThink(mobj);
return;
}
case MT_VWREF:
case MT_VWREB:
{
@ -10358,6 +10390,30 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
break;
}
case MT_SLSTMACE:
{
Obj_SLSTMaceMobjThink(mobj);
break;
}
case MT_SSCHAIN:
{
Obj_SSChainMobjThink(mobj);
break;
}
case MT_CABOTRON:
{
Obj_SSCabotronMobjThink(mobj);
break;
}
case MT_CABOTRONSTAR:
{
Obj_SSCabotronStarMobjThink(mobj);
break;
}
default:
// check mobj against possible water content, before movement code
P_MobjCheckWater(mobj);
@ -11880,6 +11936,18 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_TRICKBALLOON_YELLOW:
Obj_TrickBalloonMobjSpawn(mobj);
break;
case MT_SS_HOLOGRAM:
Obj_SSHologramMobjSpawn(mobj);
break;
case MT_SEALEDSTAR_BUMPER:
Obj_SSBumperMobjSpawn(mobj);
break;
case MT_GACHATARGET:
Obj_SSGachaTargetMobjSpawn(mobj);
break;
case MT_CABOTRON:
Obj_SSCabotronMobjSpawn(mobj);
break;
default:
break;
}
@ -14667,6 +14735,36 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj)
Obj_FuelCanisterEmitterInit(mobj);
break;
}
case MT_SS_HOLOGRAM_ROTATOR:
{
Obj_SSHologramRotatorMapThingSpawn(mobj, mthing);
break;
}
case MT_SS_HOLOGRAM:
{
Obj_SSHologramMapThingSpawn(mobj, mthing);
break;
}
case MT_SS_COIN_CLOUD:
{
Obj_SSCoinCloudMapThingSpawn(mobj, mthing);
break;
}
case MT_SS_GOBLET_CLOUD:
{
Obj_SSGobletCloudMapThingSpawn(mobj, mthing);
break;
}
case MT_SS_LAMP:
{
Obj_SSLampMapThingSpawn(mobj, mthing);
break;
}
case MT_SSWINDOW:
{
Obj_SSWindowMapThingSpawn(mobj, mthing);
break;
}
default:
break;
}

View file

@ -1242,7 +1242,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"ridr1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boarding Rideroid"}, // Rideroid Activation
{"ridr2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rideroid Diveroll
{"ridr3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rideroid Loop
{"ridr4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Leaving Rideroid
{"ridr4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Leaving Rideroid
{"befan1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Whisking"}, // Blend Eye whisk startup
{"befan2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Whisking"}, // Blend Eye whisk
@ -1256,6 +1256,13 @@ sfxinfo_t S_sfx[NUMSFX] =
{"lcfuel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Fuel Capsule explodes"},
{"ssthnk", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, "Chain rattles"}, // SF_X8AWAYSOUND
{"powerd", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "UNDESCRIBED POWERD"},
{"vault", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "UNDESCRIBED VAULT"},
{"revcym", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "UNDESCRIBED REVCYM"},
{"ssbmpr", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "UNDESCRIBED SSBMPR"}, // SF_X4AWAYSOUND
{"chcrun", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "UNDESCRIBED CHCRUN"},
// Damage sounds
{"dmga1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},
{"dmga2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"},

View file

@ -1330,6 +1330,14 @@ typedef enum
// Fuel Capsule
sfx_lcfuel,
// Sealed Star Chain
sfx_ssthnk,
sfx_powerd,
sfx_vault,
sfx_revcym,
sfx_ssbmpr,
sfx_chcrun,
// Damage sounds
sfx_dmga1,
sfx_dmga2,