From 1aaccfcd5c304a56ec85838de8efc3e82ad7ac56 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 8 Jun 2019 09:51:46 +0200 Subject: [PATCH] Hardcoded dust devil --- src/dehacked.c | 15 +++++ src/hardware/hw_light.c | 2 + src/info.c | 94 ++++++++++++++++++++++++++ src/info.h | 17 +++++ src/p_enemy.c | 143 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 271 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 6d1f58990..bc30a579d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2393,6 +2393,7 @@ static actionpointer_t actionpointers[] = {{A_Boss5MakeItRain}, "A_BOSS5MAKEITRAIN"}, {{A_LookForBetter}, "A_LOOKFORBETTER"}, {{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"}, + {{A_DustDevilThink}, "A_DUSTDEVILTHINK"}, {{NULL}, "NONE"}, @@ -5681,6 +5682,17 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARIDSIGN_CACTI", "S_ARIDSIGN_SHARPTURN", + //Dust devil + "S_DUSTDEVIL", + "S_DUSTLAYER1", + "S_DUSTLAYER2", + "S_DUSTLAYER3", + "S_DUSTLAYER4", + "S_DUSTLAYER5", + "S_ARIDDUST1", + "S_ARIDDUST2", + "S_ARIDDUST3", + // Flame jet "S_FLAMEJETSTND", "S_FLAMEJETSTART", @@ -7369,6 +7381,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_ARIDSIGN_CAUTION", "MT_ARIDSIGN_CACTI", "MT_ARIDSIGN_SHARPTURN", + "MT_DUSTDEVIL", + "MT_DUSTLAYER", + "MT_ARIDDUST", // Red Volcano Scenery "MT_FLAMEJET", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 90d02fdf8..017911d4c 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -350,6 +350,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_WWSG &lspr[NOLIGHT], // SPR_WWS2 &lspr[NOLIGHT], // SPR_WWS3 + &lspr[NOLIGHT], // SPR_TAZD + &lspr[NOLIGHT], // SPR_ADST // Red Volcano Scenery &lspr[REDBALL_L], // SPR_FLME diff --git a/src/info.c b/src/info.c index e03b63a65..4deb4dd3a 100644 --- a/src/info.c +++ b/src/info.c @@ -245,6 +245,8 @@ char sprnames[NUMSPRITES + 1][5] = "WWSG", // Caution Sign "WWS2", // Cacti Sign "WWS3", // Sharp Turn Sign + "TAZD", // Dust devil + "ADST", // Arid dust // Red Volcano Scenery "FLME", // Flame jet @@ -2315,6 +2317,17 @@ state_t states[NUMSTATES] = {SPR_WWS2, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_ARIDSIGN_CACTI {SPR_WWS3, FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_ARIDSIGN_SHARPTURN + // Dust devil + {SPR_NULL, 0, 1, {A_DustDevilThink}, 0, 0, S_DUSTDEVIL}, //S_DUSTDEVIL + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS70, 2 * TICRATE, {NULL}, 0, 0, S_DUSTLAYER2}, //S_DUSTLAYER1 + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS70, 5, {NULL}, 0, 0, S_DUSTLAYER3}, //S_DUSTLAYER2 + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS80, 5, {NULL}, 0, 0, S_DUSTLAYER4}, //S_DUSTLAYER3 + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS80, 5, {NULL}, 0, 0, S_DUSTLAYER5}, //S_DUSTLAYER4 + {SPR_TAZD, 1|FF_PAPERSPRITE|FF_TRANS90, 5, {NULL}, 0, 0, S_NULL}, //S_DUSTLAYER5 + {SPR_ADST, 0|FF_ANIMATE, 24, {NULL}, 3, 8, S_NULL}, //S_ARIDDUST1 + {SPR_ADST, 3|FF_ANIMATE, 24, {NULL}, 3, 8, S_NULL}, //S_ARIDDUST2 + {SPR_ADST, 6|FF_ANIMATE, 24, {NULL}, 3, 8, S_NULL}, //S_ARIDDUST3 + // Flame jet {SPR_NULL, 0, 2*TICRATE, {NULL}, 0, 0, S_FLAMEJETSTART}, // S_FLAMEJETSTND {SPR_NULL, 0, 3*TICRATE, {A_ToggleFlameJet}, 0, 0, S_FLAMEJETSTOP}, // S_FLAMEJETSTART @@ -11416,6 +11429,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_DUSTDEVIL + 1218, // doomednum + S_DUSTDEVIL, // 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 + 2, // speed + 80*FRACUNIT, // radius + 416*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_s3k4b, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_DUSTLAYER + -1, // doomednum + S_DUSTLAYER1, // 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 + 64*FRACUNIT, // radius + 256*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_ARIDDUST + -1, // doomednum + S_ARIDDUST1, // 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 + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_FLAMEJET 1300, // doomednum S_FLAMEJETSTND, // spawnstate diff --git a/src/info.h b/src/info.h index fbe8ed8d7..7a5bc960d 100644 --- a/src/info.h +++ b/src/info.h @@ -251,6 +251,7 @@ void A_Boss5PinchShot(); void A_Boss5MakeItRain(); void A_LookForBetter(); void A_Boss5BombExplode(); +void A_DustDevilThink(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 @@ -476,6 +477,8 @@ typedef enum sprite SPR_WWSG, // Caution Sign SPR_WWS2, // Cacti Sign SPR_WWS3, // Sharp Turn Sign + SPR_TAZD, // Dust devil + SPR_ADST, // Arid dust // Red Volcano Scenery SPR_FLME, // Flame jet @@ -2426,6 +2429,17 @@ typedef enum state S_ARIDSIGN_CACTI, S_ARIDSIGN_SHARPTURN, + //Dust devil + S_DUSTDEVIL, + S_DUSTLAYER1, + S_DUSTLAYER2, + S_DUSTLAYER3, + S_DUSTLAYER4, + S_DUSTLAYER5, + S_ARIDDUST1, + S_ARIDDUST2, + S_ARIDDUST3, + // Flame jet S_FLAMEJETSTND, S_FLAMEJETSTART, @@ -4134,6 +4148,9 @@ typedef enum mobj_type MT_ARIDSIGN_CAUTION, // Caution Sign MT_ARIDSIGN_CACTI, // Cacti Sign MT_ARIDSIGN_SHARPTURN, // Sharp Turn Sign + MT_DUSTDEVIL, + MT_DUSTLAYER, + MT_ARIDDUST, // Red Volcano Scenery MT_FLAMEJET, diff --git a/src/p_enemy.c b/src/p_enemy.c index 664e3b9b0..ba1fe266c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -280,6 +280,7 @@ void A_Boss5PinchShot(mobj_t *actor); void A_Boss5MakeItRain(mobj_t *actor); void A_LookForBetter(mobj_t *actor); void A_Boss5BombExplode(mobj_t *actor); +void A_DustDevilThink(mobj_t *actor); //for p_enemy.c // @@ -12521,3 +12522,145 @@ void A_Boss5BombExplode(mobj_t *actor) } quake.radius = 20*actor->radius; } + +static mobj_t *dustdevil; + +static boolean PIT_DustDevilLaunch(mobj_t *thing) +{ + player_t *player = thing->player; + + if (!player) + return true; + + if (abs(thing->x - dustdevil->x) > dustdevil->radius || abs(thing->y - dustdevil->y) > dustdevil->radius) + return true; + + if (thing->z + thing->height >= dustdevil->z && dustdevil->z + dustdevil->height >= thing->z) { + fixed_t pos = thing->z - dustdevil->z; + fixed_t thrust = max(FixedDiv(pos, dustdevil->height) * 20, 8 * FRACUNIT); + angle_t fa = R_PointToAngle2(thing->x, thing->y, dustdevil->x, dustdevil->y) >> ANGLETOFINESHIFT; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + fixed_t thresh = dustdevil->scale * 20; + + //Player in the swirl part. + if (dustdevil->height - pos > thresh) + { + fixed_t dist = FixedHypot(thing->x - dustdevil->x, thing->y - dustdevil->y); + fixed_t dragamount = 6 * FRACUNIT; + fixed_t x, y; + + if (player->powers[pw_nocontrol] == 0) + A_PlayActiveSound(dustdevil); + player->powers[pw_nocontrol] = 2; + player->drawangle += ANG20; + P_SetPlayerMobjState(thing, S_PLAY_PAIN); + + if (dist > dragamount) + { + x = thing->x + FixedMul(c, dragamount); + y = thing->y + FixedMul(s, dragamount); + } + else + { + x = dustdevil->x; + y = dustdevil->y; + } + P_TryMove(thing, x - thing->momx, y - thing->momy, true); + } + else + { //Player on the top of the tornado. + thing->z = dustdevil->z + dustdevil->height; + thrust = 20 * FRACUNIT; + player->powers[pw_nocontrol] = 0; + S_StartSound(thing, sfx_wdjump); + P_SetPlayerMobjState(thing, S_PLAY_FALL); + player->pflags &= ~PF_JUMPED; + } + + thing->momz = thrust; + } + + return true; +} + +// Function: A_DustDevilThink +// +// Description: Thinker for the dust devil. +// +// var1 = unused +// var2 = unused +// +void A_DustDevilThink(mobj_t *actor) +{ + fixed_t scale = actor->scale; + mobj_t *layer = actor->tracer; + INT32 bx, by, xl, xh, yl, yh; + fixed_t radius = actor->radius + MAXRADIUS; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_DustDevilThink", actor)) + return; +#endif + + //Chained thinker for the spiralling dust column. + while (layer) { + angle_t fa = layer->angle >> ANGLETOFINESHIFT; + P_TeleportMove(layer, layer->x + 5 * FixedMul(scale, FINECOSINE(fa)), layer->y + 5 * FixedMul(scale, FINESINE(fa)), layer->z); + layer->scale = scale; + layer->angle += ANG10 / 2; + layer->momx = actor->momx; + layer->momy = actor->momy; + layer = layer->tracer; + } + + //Spawn random dust around the column on the base. + //TODO: Dust shouldn't be shrinking + if (P_IsObjectOnGround(actor)) { + angle_t dustang = ((P_RandomRange(0, 7)*ANGLE_45)>>ANGLETOFINESHIFT) & FINEMASK; + mobj_t *dust = P_SpawnMobj(actor->x + 96 * FixedMul(scale, FINECOSINE(dustang)), actor->y + 96 * FixedMul(scale, FINESINE(dustang)), actor->z, MT_ARIDDUST); + P_SetMobjState(dust, dust->info->spawnstate + P_RandomRange(0, 2)); + dust->scale = scale * 3; + } + + actor->extravalue1++; + if (actor->extravalue1 == 12) { + size_t i = 0; + actor->extravalue1 = 0; + + //Create a set of items for the rising dust column + for (; i <= 3; i++) { + fixed_t fa = (ANGLE_90*i) >> ANGLETOFINESHIFT; + fixed_t px = actor->x + 70 * FixedMul(scale, FINECOSINE(fa)); + fixed_t py = actor->y + 70 * FixedMul(scale, FINESINE(fa)); + fixed_t pz = actor->z; + + layer = P_SpawnMobj(px, py, pz, MT_DUSTLAYER); + layer->momz = 5 * scale; + layer->angle = ANGLE_90 + ANGLE_90*i; + layer->extravalue1 = TICRATE * 3; + + //Chain them + layer->tracer = actor->tracer; + actor->tracer = layer; + } + } + + //The physics are handled here. + yh = (unsigned)(actor->y + radius - bmaporgy) >> MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - radius - bmaporgy) >> MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + radius - bmaporgx) >> MAPBLOCKSHIFT; + xl = (unsigned)(actor->x - radius - bmaporgx) >> MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); + + dustdevil = actor; + + for (bx = xl; bx <= xh; bx++) + for (by = yl; by <= yh; by++) + P_BlockThingsIterator(bx, by, PIT_DustDevilLaunch); + + //Whirlwind sound effect. + if (leveltime % 70 == 0) + S_StartSound(actor, sfx_s3kcel); +}