Hardcoded dust devil

This commit is contained in:
MascaraSnake 2019-06-08 09:51:46 +02:00
parent 68585dbc70
commit 1aaccfcd5c
5 changed files with 271 additions and 0 deletions

View File

@ -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",

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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);
}