diff --git a/src/dehacked.c b/src/dehacked.c index ae2eb9214..72db4306c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2431,6 +2431,9 @@ static actionpointer_t actionpointers[] = {{A_SaloonDoorSpawn}, "A_SALOONDOORSPAWN"}, {{A_MinecartSparkThink}, "A_MINECARTSPARKTHINK"}, {{A_ModuloToState}, "A_MODULOTOSTATE"}, + {{A_LavafallRocks}, "A_LAVAFALLROCKS"}, + {{A_LavafallLava}, "A_LAVAFALLLAVA"}, + {{A_FallingLavaCheck}, "A_FALLINGLAVACHECK"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -5824,6 +5827,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FLAMEJETFLAMEB2", "S_FLAMEJETFLAMEB3", + // Lavafall + "S_LAVAFALL_DORMANT", + "S_LAVAFALL_TELL", + "S_LAVAFALL_SHOOT", + "S_LAVAFALL_LAVA1", + "S_LAVAFALL_LAVA2", + "S_LAVAFALL_LAVA3", + "S_LAVAFALLROCK1", + "S_LAVAFALLROCK2", + "S_LAVAFALLROCK3", + "S_LAVAFALLROCK4", + // RVZ scenery "S_BIGFERNLEAF", "S_BIGFERN1", @@ -7548,6 +7563,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FLAMEJETFLAMEB", // Blade's flame + "MT_LAVAFALL", + "MT_LAVAFALL_LAVA", + "MT_LAVAFALLROCK", + "MT_BIGFERNLEAF", "MT_BIGFERN", "MT_JUNGLEPALM", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index e1f2a9699..1e5a01674 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -373,6 +373,7 @@ light_t *t_lspr[NUMSPRITES] = // Red Volcano Scenery &lspr[REDBALL_L], // SPR_FLME &lspr[REDBALL_L], // SPR_DFLM + &lspr[NOLIGHT], // SPR_LFAL &lspr[NOLIGHT], // SPR_JPLA &lspr[NOLIGHT], // SPR_TFLO &lspr[NOLIGHT], // SPR_WVIN diff --git a/src/info.c b/src/info.c index 86fe138c5..88e857716 100644 --- a/src/info.c +++ b/src/info.c @@ -268,6 +268,7 @@ char sprnames[NUMSPRITES + 1][5] = // Red Volcano Scenery "FLME", // Flame jet "DFLM", // Blade's flame + "LFAL", // Lavafall "JPLA", // Jungle palm "TFLO", // Torch flower "WVIN", // Wall vines @@ -2456,6 +2457,18 @@ state_t states[NUMSTATES] = {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40, 1, {A_MoveRelative}, 0, 7, S_FLAMEJETFLAMEB3}, // S_FLAMEJETFLAMEB2 {SPR_DFLM, FF_FULLBRIGHT|FF_TRANS40|FF_ANIMATE, (12*7), {NULL}, 7, 12, S_NULL}, // S_FLAMEJETFLAMEB3 + // Lavafall + {SPR_LFAL, 5, 1, {NULL}, 0, 0, S_LAVAFALL_DORMANT}, // S_LAVAFALL_DORMANT + {SPR_LFAL, 6|FF_ANIMATE, 4, {A_LavafallRocks}, 2, 2, S_LAVAFALL_TELL}, // S_LAVAFALL_TELL + {SPR_LFAL, 9|FF_FULLBRIGHT|FF_ANIMATE, 2, {A_LavafallLava}, 2, 1, S_LAVAFALL_SHOOT}, // S_LAVAFALL_SHOOT + {SPR_LFAL, FF_FULLBRIGHT, 1, {A_FallingLavaCheck}, 0, 0, S_LAVAFALL_LAVA2}, // S_LAVAFALL_LAVA1 + {SPR_LFAL, FF_FULLBRIGHT, 1, {A_FallingLavaCheck}, 0, 0, S_LAVAFALL_LAVA1}, // S_LAVAFALL_LAVA2 + {SPR_LFAL, 2|FF_FULLBRIGHT|FF_ANIMATE, 9, {NULL}, 3, 3, S_NULL}, // S_LAVAFALL_LAVA3 + {SPR_LFAL, 11, 3, {NULL}, 0, 0, S_LAVAFALLROCK2}, // S_LAVAFALLROCK1 + {SPR_LFAL, 12, 3, {NULL}, 0, 0, S_LAVAFALLROCK3}, // S_LAVAFALLROCK2 + {SPR_LFAL, 13, 3, {NULL}, 0, 0, S_LAVAFALLROCK4}, // S_LAVAFALLROCK3 + {SPR_LFAL, 14, 3, {NULL}, 0, 0, S_LAVAFALLROCK1}, // S_LAVAFALLROCK4 + // RVZ scenery {SPR_JPLA, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_BIGFERNLEAF {SPR_JPLA, 1, 1, {NULL}, 0, 0, S_BIGFERN2}, // S_BIGFERN1 @@ -12575,6 +12588,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_LAVAFALL + 1304, // doomednum + S_LAVAFALL_DORMANT, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_lvfal1, // seesound + 8, // reactiontime + sfx_s3kd5l, // 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 + 30*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_SPAWNCEILING, // flags + S_NULL // raisestate + }, + + { // MT_LAVAFALL_LAVA + -1, // doomednum + S_LAVAFALL_LAVA1, // 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_LAVAFALL_LAVA3, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 30*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_PAIN|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_LAVAFALLROCK + -1, // doomednum + S_LAVAFALLROCK1, // 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 + 0, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP, // flags + S_NULL // raisestate + }, + { // MT_BIGFERNLEAF -1, // doomednum S_BIGFERNLEAF, // spawnstate diff --git a/src/info.h b/src/info.h index 9f7249f19..0fe200cbd 100644 --- a/src/info.h +++ b/src/info.h @@ -266,6 +266,9 @@ void A_SnapperThinker(); void A_SaloonDoorSpawn(); void A_MinecartSparkThink(); void A_ModuloToState(); +void A_LavafallRocks(); +void A_LavafallLava(); +void A_FallingLavaCheck(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 512 @@ -514,6 +517,7 @@ typedef enum sprite // Red Volcano Scenery SPR_FLME, // Flame jet SPR_DFLM, // Blade's flame + SPR_LFAL, // Lavafall SPR_JPLA, // Jungle palm SPR_TFLO, // Torch flower SPR_WVIN, // Wall vines @@ -2575,6 +2579,18 @@ typedef enum state S_FLAMEJETFLAMEB2, S_FLAMEJETFLAMEB3, + // Lavafall + S_LAVAFALL_DORMANT, + S_LAVAFALL_TELL, + S_LAVAFALL_SHOOT, + S_LAVAFALL_LAVA1, + S_LAVAFALL_LAVA2, + S_LAVAFALL_LAVA3, + S_LAVAFALLROCK1, + S_LAVAFALLROCK2, + S_LAVAFALLROCK3, + S_LAVAFALLROCK4, + // RVZ scenery S_BIGFERNLEAF, S_BIGFERN1, @@ -4321,6 +4337,10 @@ typedef enum mobj_type MT_FLAMEJETFLAMEB, // Blade's flame + MT_LAVAFALL, + MT_LAVAFALL_LAVA, + MT_LAVAFALLROCK, + MT_BIGFERNLEAF, MT_BIGFERN, MT_JUNGLEPALM, diff --git a/src/p_enemy.c b/src/p_enemy.c index e3f169784..5b82e45b4 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -296,6 +296,9 @@ void A_SnapperThinker(mobj_t *actor); void A_SaloonDoorSpawn(mobj_t *actor); void A_MinecartSparkThink(mobj_t *actor); void A_ModuloToState(mobj_t *actor); +void A_LavafallRocks(mobj_t *actor); +void A_LavafallLava(mobj_t *actor); +void A_FallingLavaCheck(mobj_t *actor); //for p_enemy.c @@ -13738,3 +13741,69 @@ void A_ModuloToState(mobj_t *actor) P_SetMobjState(actor, (locvar2)); modulothing++; } + +// Function: A_LavafallRocks +// +// Description: Spawn random rock particles. +// +// var1 = unused +// var2 = unused +// +void A_LavafallRocks(mobj_t *actor) +{ +#ifdef HAVE_BLUA + if (LUA_CallAction("A_LavafallRocks", actor)) + return; +#endif + + angle_t fa = (FixedAngle(P_RandomKey(360) << FRACBITS) >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t offset = P_RandomRange(4, 12) << FRACBITS; + fixed_t xoffs = FixedMul(FINECOSINE(fa), actor->radius + offset); + fixed_t yoffs = FixedMul(FINESINE(fa), actor->radius + offset); + mobj_t *particle = P_SpawnMobjFromMobj(actor, xoffs, yoffs, 0, MT_LAVAFALLROCK); + P_SetMobjState(particle, S_LAVAFALLROCK1 + P_RandomRange(0, 3)); +} + +// Function: A_LavafallLava +// +// Description: Spawn lava from lavafall. +// +// var1 = unused +// var2 = unused +// +void A_LavafallLava(mobj_t *actor) +{ +#ifdef HAVE_BLUA + if (LUA_CallAction("A_LavafallLava", actor)) + return; +#endif + + if ((40 - actor->fuse) % (2*(actor->scale >> FRACBITS))) + return; + + mobj_t *lavafall = P_SpawnMobjFromMobj(actor, 0, 0, -8*FRACUNIT, MT_LAVAFALL_LAVA); + lavafall->momz = -25*FRACUNIT; +} + +// Function: A_FallingLavaCheck +// +// Description: If actor hits the ground or a water surface, enter the death animation. +// +// var1 = unused +// var2 = unused +// +void A_FallingLavaCheck(mobj_t *actor) +{ +#ifdef HAVE_BLUA + if (LUA_CallAction("A_FallingLavaCheck", actor)) + return; +#endif + + if (actor->eflags & MFE_TOUCHWATER || P_IsObjectOnGround(actor)) + { + actor->flags = MF_NOGRAVITY|MF_NOCLIPTHING; + actor->momz = 0; + actor->z = actor->watertop; + P_SetMobjState(actor, actor->info->deathstate); + } +} \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index b42067453..13d2d82c0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9008,6 +9008,10 @@ void P_MobjThinker(mobj_t *mobj) } mobj->flags2 ^= MF2_DONTDRAW; break; + case MT_LAVAFALLROCK: + if (P_IsObjectOnGround(mobj)) + P_RemoveMobj(mobj); + break; case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) { @@ -9223,6 +9227,27 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s case MT_NIGHTSCORE: P_RemoveMobj(mobj); return; + case MT_LAVAFALL: + if (mobj->state - states == S_LAVAFALL_DORMANT) + { + mobj->fuse = 30; + P_SetMobjState(mobj, S_LAVAFALL_TELL); + S_StartSound(mobj, mobj->info->seesound); + } + else if (mobj->state - states == S_LAVAFALL_TELL) + { + mobj->fuse = 40; + P_SetMobjState(mobj, S_LAVAFALL_SHOOT); + S_StopSound(mobj); + S_StartSound(mobj, mobj->info->attacksound); + } + else + { + mobj->fuse = 30; + P_SetMobjState(mobj, S_LAVAFALL_DORMANT); + S_StopSound(mobj); + } + return; case MT_PLAYER: break; // don't remove default: @@ -11831,6 +11856,14 @@ ML_EFFECT5 : Don't stop thinking when too far away if (mthing->angle > 0) mobj->tics += mthing->angle; break; + case MT_LAVAFALL: + mobj->fuse = 30 + mthing->angle; + if (mthing->options & MTF_AMBUSH) + { + P_SetScale(mobj, 2*mobj->scale); + mobj->destscale = mobj->scale; + } + break; default: break; } diff --git a/src/sounds.c b/src/sounds.c index 11ba1e0bc..5a498b358 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -199,6 +199,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"chuchu", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Train horn"}, {"bsnipe", false, 200, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Home-run smash"}, {"sprong", false, 112, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power spring"}, + {"lvfal1", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rumble"}, // Menu, interface {"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"}, diff --git a/src/sounds.h b/src/sounds.h index 20f89d9fb..f1221e6fe 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -265,6 +265,7 @@ typedef enum sfx_chuchu, sfx_bsnipe, sfx_sprong, + sfx_lvfal1, // Menu, interface sfx_chchng,