From 1aaccfcd5c304a56ec85838de8efc3e82ad7ac56 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 8 Jun 2019 09:51:46 +0200 Subject: [PATCH 01/51] 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); +} From 5ac594abf57fcdd329a8128851399eee9e0ce326 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 8 Jun 2019 14:12:39 +0200 Subject: [PATCH 02/51] Fixed dust scaling, changed sound captions --- src/p_enemy.c | 6 +++--- src/sounds.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index ba1fe266c..781f0ff15 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -12596,7 +12596,7 @@ 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; + fixed_t radius = actor->radius; #ifdef HAVE_BLUA if (LUA_CallAction("A_DustDevilThink", actor)) @@ -12615,12 +12615,12 @@ void A_DustDevilThink(mobj_t *actor) } //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; + dust->destscale = scale * 3; + P_SetScale(dust, dust->destscale); } actor->extravalue1++; diff --git a/src/sounds.c b/src/sounds.c index 66d498838..cd5abd1f5 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -311,7 +311,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pulse"}, {"s3k49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"}, {"s3k4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Grab"}, - {"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Water splash"}, + {"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, {"s3k4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy hit"}, {"s3k4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing bullet"}, {"s3k4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Big explosion"}, @@ -460,7 +460,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kcds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, {"s3kcdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto {"s3kces", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind tunnel"}, - {"s3kcel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind tunnel"}, // ditto + {"s3kcel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dust devil"}, // ditto {"s3kcfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s3kcfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto {"s3kd0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising"}, From 3d65ec7426186f952979b0f26e8857f86b6c8874 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 8 Jun 2019 14:45:01 +0200 Subject: [PATCH 03/51] Changed cacti widths --- src/info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 4deb4dd3a..25eda22e0 100644 --- a/src/info.c +++ b/src/info.c @@ -11230,7 +11230,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 40*FRACUNIT, // radius + 32*FRACUNIT, // radius 128*FRACUNIT, // height 0, // display offset 100, // mass @@ -11257,7 +11257,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 24*FRACUNIT, // radius + 20*FRACUNIT, // radius 132*FRACUNIT, // height 0, // display offset 100, // mass From 546af19c8204fba2801c32208768433d62b20103 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 8 Jun 2019 15:50:01 +0200 Subject: [PATCH 04/51] Hardcoded oil lamp --- src/dehacked.c | 7 +++++- src/hardware/hw_light.c | 2 ++ src/info.c | 49 ++++++++++++++++++++++++++++++++++------- src/info.h | 9 +++++++- src/p_mobj.c | 7 ++++++ 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index bc30a579d..986ef2eef 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5682,7 +5682,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARIDSIGN_CACTI", "S_ARIDSIGN_SHARPTURN", - //Dust devil + // Oil lamp + "S_OILLAMP", + "S_OILLAMPFLARE", + + // Dust devil "S_DUSTDEVIL", "S_DUSTLAYER1", "S_DUSTLAYER2", @@ -7381,6 +7385,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_ARIDSIGN_CAUTION", "MT_ARIDSIGN_CACTI", "MT_ARIDSIGN_SHARPTURN", + "MT_OILLAMP", "MT_DUSTDEVIL", "MT_DUSTLAYER", "MT_ARIDDUST", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 017911d4c..793709a2b 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_OILL + &lspr[NOLIGHT], // SPR_OILF &lspr[NOLIGHT], // SPR_TAZD &lspr[NOLIGHT], // SPR_ADST diff --git a/src/info.c b/src/info.c index 25eda22e0..2b7929ff0 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 + "OILL", // Oil lamp + "OILF", // Oil lamp flare "TAZD", // Dust devil "ADST", // Arid dust @@ -2317,16 +2319,20 @@ 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 + // Oil lamp + {SPR_OILL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_OILLAMP + {SPR_OILF, FF_TRANS90|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_OILLAMPFLARE + // 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 + {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 @@ -11429,6 +11435,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_OILLAMP + 1215, // doomednum + S_OILLAMP, // 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 + 22*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_s3k4b, // activesound + MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SPAWNCEILING, // flags + S_NULL // raisestate + }, + { // MT_DUSTDEVIL 1218, // doomednum S_DUSTDEVIL, // spawnstate diff --git a/src/info.h b/src/info.h index 7a5bc960d..e1ccecf8a 100644 --- a/src/info.h +++ b/src/info.h @@ -477,6 +477,8 @@ typedef enum sprite SPR_WWSG, // Caution Sign SPR_WWS2, // Cacti Sign SPR_WWS3, // Sharp Turn Sign + SPR_OILL, // Oil lamp + SPR_OILF, // Oil lamp flare SPR_TAZD, // Dust devil SPR_ADST, // Arid dust @@ -2429,7 +2431,11 @@ typedef enum state S_ARIDSIGN_CACTI, S_ARIDSIGN_SHARPTURN, - //Dust devil + // Oil lamp + S_OILLAMP, + S_OILLAMPFLARE, + + // Dust devil S_DUSTDEVIL, S_DUSTLAYER1, S_DUSTLAYER2, @@ -4148,6 +4154,7 @@ typedef enum mobj_type MT_ARIDSIGN_CAUTION, // Caution Sign MT_ARIDSIGN_CACTI, // Cacti Sign MT_ARIDSIGN_SHARPTURN, // Sharp Turn Sign + MT_OILLAMP, MT_DUSTDEVIL, MT_DUSTLAYER, MT_ARIDDUST, diff --git a/src/p_mobj.c b/src/p_mobj.c index bc43fbe1e..649f4b330 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9152,6 +9152,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_FBOMB: mobj->flags2 |= MF2_EXPLOSION; break; + case MT_OILLAMP: + { + mobj_t* overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + P_SetTarget(&overlay->target, mobj); + P_SetMobjState(overlay, S_OILLAMPFLARE); + break; + } default: break; } From 7b603f4ac8abff6a783f91fa1cf40cb0f4d46000 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 9 Jun 2019 10:51:33 +0200 Subject: [PATCH 05/51] Hardcoded the TNT barrels and proximity shell (using mazmazz's A_TNTExplode implementation from the minecart branch) --- src/dehacked.c | 42 ++++++++++++++- src/hardware/hw_light.c | 2 + src/info.c | 92 ++++++++++++++++++++++++++++++++ src/info.h | 41 ++++++++++++++ src/p_enemy.c | 115 ++++++++++++++++++++++++++++++++++++++++ src/p_map.c | 35 ++++++++++++ src/p_mobj.c | 3 ++ src/sounds.c | 3 +- src/sounds.h | 1 + 9 files changed, 331 insertions(+), 3 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 986ef2eef..bae63eb08 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2394,8 +2394,8 @@ static actionpointer_t actionpointers[] = {{A_LookForBetter}, "A_LOOKFORBETTER"}, {{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"}, {{A_DustDevilThink}, "A_DUSTDEVILTHINK"}, - - {{NULL}, "NONE"}, + {{A_TNTExplode}, "A_TNTEXPLODE"}, + {{NULL}, "NONE"}, // This NULL entry must be the last in the list {{NULL}, NULL}, @@ -5686,6 +5686,42 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_OILLAMP", "S_OILLAMPFLARE", + // TNT barrel + "S_TNTBARREL_STND1", + "S_TNTBARREL_EXPL1", + "S_TNTBARREL_EXPL2", + "S_TNTBARREL_EXPL3", + "S_TNTBARREL_EXPL4", + "S_TNTBARREL_EXPL5", + "S_TNTBARREL_EXPL6", + "S_TNTBARREL_FLYING", + + // TNT proximity shell + "S_PROXIMITY_TNT", + "S_PROXIMITY_TNT_TRIGGER1", + "S_PROXIMITY_TNT_TRIGGER2", + "S_PROXIMITY_TNT_TRIGGER3", + "S_PROXIMITY_TNT_TRIGGER4", + "S_PROXIMITY_TNT_TRIGGER5", + "S_PROXIMITY_TNT_TRIGGER6", + "S_PROXIMITY_TNT_TRIGGER7", + "S_PROXIMITY_TNT_TRIGGER8", + "S_PROXIMITY_TNT_TRIGGER9", + "S_PROXIMITY_TNT_TRIGGER10", + "S_PROXIMITY_TNT_TRIGGER11", + "S_PROXIMITY_TNT_TRIGGER12", + "S_PROXIMITY_TNT_TRIGGER13", + "S_PROXIMITY_TNT_TRIGGER14", + "S_PROXIMITY_TNT_TRIGGER15", + "S_PROXIMITY_TNT_TRIGGER16", + "S_PROXIMITY_TNT_TRIGGER17", + "S_PROXIMITY_TNT_TRIGGER18", + "S_PROXIMITY_TNT_TRIGGER19", + "S_PROXIMITY_TNT_TRIGGER20", + "S_PROXIMITY_TNT_TRIGGER21", + "S_PROXIMITY_TNT_TRIGGER22", + "S_PROXIMITY_TNT_TRIGGER23", + // Dust devil "S_DUSTDEVIL", "S_DUSTLAYER1", @@ -7386,6 +7422,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_ARIDSIGN_CACTI", "MT_ARIDSIGN_SHARPTURN", "MT_OILLAMP", + "MT_TNTBARREL", + "MT_PROXIMITYTNT", "MT_DUSTDEVIL", "MT_DUSTLAYER", "MT_ARIDDUST", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 793709a2b..1de293b54 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -352,6 +352,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_WWS3 &lspr[NOLIGHT], // SPR_OILL &lspr[NOLIGHT], // SPR_OILF + &lspr[NOLIGHT], // SPR_BARR + &lspr[NOLIGHT], // SPR_REMT &lspr[NOLIGHT], // SPR_TAZD &lspr[NOLIGHT], // SPR_ADST diff --git a/src/info.c b/src/info.c index 2b7929ff0..a513800a2 100644 --- a/src/info.c +++ b/src/info.c @@ -247,6 +247,8 @@ char sprnames[NUMSPRITES + 1][5] = "WWS3", // Sharp Turn Sign "OILL", // Oil lamp "OILF", // Oil lamp flare + "BARR", // TNT barrel + "REMT", // TNT proximity shell "TAZD", // Dust devil "ADST", // Arid dust @@ -2323,6 +2325,42 @@ state_t states[NUMSTATES] = {SPR_OILL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_OILLAMP {SPR_OILF, FF_TRANS90|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_OILLAMPFLARE + // TNT barrel + {SPR_BARR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_STND1 + {SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_TNTBARREL_EXPL2}, // S_TNTBARREL_EXPL1 + {SPR_BARX, 1|FF_FULLBRIGHT, 2, {A_TNTExplode}, MT_TNTDUST, 0, S_TNTBARREL_EXPL3}, // S_TNTBARREL_EXPL2 + {SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_TNTBARREL_EXPL4}, // S_TNTBARREL_EXPL3 + {SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4 + {SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5 + {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL6 + {SPR_BARR, 1|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_TNTBARREL_FLYING + + // TNT proximity shell + {SPR_REMT, 0, 10, {A_Look}, 33554433, 0, S_PROXIMITY_TNT}, // S_PROXIMITY_TNT + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER2}, // S_PROXIMITY_TNT_TRIGGER1 + {SPR_REMT, 0, 16, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER3}, // S_PROXIMITY_TNT_TRIGGER2 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER4}, // S_PROXIMITY_TNT_TRIGGER3 + {SPR_REMT, 0, 16, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER5}, // S_PROXIMITY_TNT_TRIGGER4 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER6}, // S_PROXIMITY_TNT_TRIGGER5 + {SPR_REMT, 0, 4, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER7}, // S_PROXIMITY_TNT_TRIGGER6 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER8}, // S_PROXIMITY_TNT_TRIGGER7 + {SPR_REMT, 0, 4, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER9}, // S_PROXIMITY_TNT_TRIGGER8 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER10}, // S_PROXIMITY_TNT_TRIGGER9 + {SPR_REMT, 0, 4, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER11}, // S_PROXIMITY_TNT_TRIGGER10 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER12}, // S_PROXIMITY_TNT_TRIGGER11 + {SPR_REMT, 0, 4, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER13}, // S_PROXIMITY_TNT_TRIGGER12 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER14}, // S_PROXIMITY_TNT_TRIGGER13 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER15}, // S_PROXIMITY_TNT_TRIGGER14 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER16}, // S_PROXIMITY_TNT_TRIGGER15 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER17}, // S_PROXIMITY_TNT_TRIGGER16 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER18}, // S_PROXIMITY_TNT_TRIGGER17 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER19}, // S_PROXIMITY_TNT_TRIGGER18 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER20}, // S_PROXIMITY_TNT_TRIGGER19 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER21}, // S_PROXIMITY_TNT_TRIGGER20 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_PROXIMITY_TNT_TRIGGER22}, // S_PROXIMITY_TNT_TRIGGER21 + {SPR_REMT, 0, 2, {NULL}, 0, 0, S_PROXIMITY_TNT_TRIGGER23}, // S_PROXIMITY_TNT_TRIGGER22 + {SPR_REMT, 1|FF_FULLBRIGHT, 1, {A_PlayActiveSound}, 0, 0, S_TNTBARREL_EXPL1}, // S_PROXIMITY_TNT_TRIGGER23 + // 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 @@ -11462,6 +11500,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_TNTBARREL + 1216, // doomednum + S_TNTBARREL_STND1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_bowl, // attacksound + S_TNTBARREL_EXPL1, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_TNTBARREL_FLYING, // missilestate + S_TNTBARREL_EXPL1, // deathstate + S_NULL, // xdeathstate + sfx_s3k4e, // deathsound + 0, // speed + 24*FRACUNIT, // radius + 63*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_s3k8d, // activesound + MF_SOLID|MF_SHOOTABLE|MF_ENEMY, // flags + S_NULL // raisestate + }, + + { // MT_PROXIMITYTNT + 1217, // doomednum + S_PROXIMITY_TNT, // spawnstate + 1, // spawnhealth + S_PROXIMITY_TNT_TRIGGER1, // seestate + sfx_s3k5c, // 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_s3k4e, // deathsound + 0, // speed + 64*FRACUNIT, // radius + 40*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_s3k89, // activesound + MF_SOLID, // flags + S_NULL // raisestate + }, + { // MT_DUSTDEVIL 1218, // doomednum S_DUSTDEVIL, // spawnstate diff --git a/src/info.h b/src/info.h index e1ccecf8a..e2380a7ad 100644 --- a/src/info.h +++ b/src/info.h @@ -252,6 +252,7 @@ void A_Boss5MakeItRain(); void A_LookForBetter(); void A_Boss5BombExplode(); void A_DustDevilThink(); +void A_TNTExplode(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 @@ -479,6 +480,8 @@ typedef enum sprite SPR_WWS3, // Sharp Turn Sign SPR_OILL, // Oil lamp SPR_OILF, // Oil lamp flare + SPR_BARR, // TNT barrel + SPR_REMT, // TNT proximity shell SPR_TAZD, // Dust devil SPR_ADST, // Arid dust @@ -2435,6 +2438,42 @@ typedef enum state S_OILLAMP, S_OILLAMPFLARE, + // TNT barrel + S_TNTBARREL_STND1, + S_TNTBARREL_EXPL1, + S_TNTBARREL_EXPL2, + S_TNTBARREL_EXPL3, + S_TNTBARREL_EXPL4, + S_TNTBARREL_EXPL5, + S_TNTBARREL_EXPL6, + S_TNTBARREL_FLYING, + + // TNT proximity shell + S_PROXIMITY_TNT, + S_PROXIMITY_TNT_TRIGGER1, + S_PROXIMITY_TNT_TRIGGER2, + S_PROXIMITY_TNT_TRIGGER3, + S_PROXIMITY_TNT_TRIGGER4, + S_PROXIMITY_TNT_TRIGGER5, + S_PROXIMITY_TNT_TRIGGER6, + S_PROXIMITY_TNT_TRIGGER7, + S_PROXIMITY_TNT_TRIGGER8, + S_PROXIMITY_TNT_TRIGGER9, + S_PROXIMITY_TNT_TRIGGER10, + S_PROXIMITY_TNT_TRIGGER11, + S_PROXIMITY_TNT_TRIGGER12, + S_PROXIMITY_TNT_TRIGGER13, + S_PROXIMITY_TNT_TRIGGER14, + S_PROXIMITY_TNT_TRIGGER15, + S_PROXIMITY_TNT_TRIGGER16, + S_PROXIMITY_TNT_TRIGGER17, + S_PROXIMITY_TNT_TRIGGER18, + S_PROXIMITY_TNT_TRIGGER19, + S_PROXIMITY_TNT_TRIGGER20, + S_PROXIMITY_TNT_TRIGGER21, + S_PROXIMITY_TNT_TRIGGER22, + S_PROXIMITY_TNT_TRIGGER23, + // Dust devil S_DUSTDEVIL, S_DUSTLAYER1, @@ -4155,6 +4194,8 @@ typedef enum mobj_type MT_ARIDSIGN_CACTI, // Cacti Sign MT_ARIDSIGN_SHARPTURN, // Sharp Turn Sign MT_OILLAMP, + MT_TNTBARREL, + MT_PROXIMITYTNT, MT_DUSTDEVIL, MT_DUSTLAYER, MT_ARIDDUST, diff --git a/src/p_enemy.c b/src/p_enemy.c index 781f0ff15..76ad8e234 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -281,6 +281,7 @@ void A_Boss5MakeItRain(mobj_t *actor); void A_LookForBetter(mobj_t *actor); void A_Boss5BombExplode(mobj_t *actor); void A_DustDevilThink(mobj_t *actor); +void A_TNTExplode(mobj_t *actor); //for p_enemy.c // @@ -12664,3 +12665,117 @@ void A_DustDevilThink(mobj_t *actor) if (leveltime % 70 == 0) S_StartSound(actor, sfx_s3kcel); } + +// stuff used by A_TNTExplode +static mobj_t *barrel; +static fixed_t exploderadius; +static fixed_t explodethrust; + +static boolean PIT_TNTExplode(mobj_t *nearby) +{ + fixed_t dx, dy, dz; + fixed_t dm; + + if (nearby == barrel) + return true; + + dx = nearby->x - barrel->x; + dy = nearby->y - barrel->y; + dz = nearby->z - barrel->z + (nearby->height - barrel->height/2)/2; + dm = P_AproxDistance(P_AproxDistance(dx, dy), dz); + + if (dm >= exploderadius || !P_CheckSight(barrel, nearby)) // out of range or not visible + return true; + + if (barrel->type == nearby->type) // nearby is also a barrel + { + if (nearby->state == &states[nearby->info->spawnstate]) + { + if (barrel->info->attacksound) + S_StartSound(nearby, barrel->info->attacksound); + nearby->momx = FixedMul(FixedDiv(dx, dm), explodethrust); + nearby->momy = FixedMul(FixedDiv(dy, dm), explodethrust); + nearby->momz = FixedMul(FixedDiv(dz, dm), explodethrust); + nearby->flags = MF_NOBLOCKMAP|MF_MISSILE; + P_SetMobjState(nearby, nearby->info->missilestate); + } + } + else + { + if (barrel->target == nearby) + { + mobj_t *tar = barrel->target; // temporarily store barrel's target + barrel->target = NULL; + P_DamageMobj(nearby, barrel, NULL, 1, 0); + barrel->target = tar; + } + else + { + P_DamageMobj(nearby, + (barrel->target) ? barrel->target : barrel, + (barrel->target) ? barrel->target : barrel, + 1, 0); + } + } + + return true; +} + +// Function: A_TNTExplode +// +// Description: Creates a TNT explosion. Used by TNT barrels and the like. +// +// var1 = Thing type to spawn as dust. +// var2 = unused +// +void A_TNTExplode(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; + INT32 x, y; + INT32 xl, xh, yl, yh; + static mappoint_t epicenter = {0,0,0}; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_TNTExplode", actor)) + return; +#endif + + actor->flags = MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP; + actor->flags2 = MF2_EXPLOSION; + if (actor->info->deathsound) + S_StartSound(actor, actor->info->deathsound); + + explodethrust = 32*FRACUNIT; + exploderadius = 256*FRACUNIT; + + xl = (unsigned)(actor->x - exploderadius - bmaporgx)>>MAPBLOCKSHIFT; + xh = (unsigned)(actor->x + exploderadius - bmaporgx)>>MAPBLOCKSHIFT; + yl = (unsigned)(actor->y - exploderadius - bmaporgy)>>MAPBLOCKSHIFT; + yh = (unsigned)(actor->y + exploderadius - bmaporgy)>>MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); + + barrel = actor; + + for (x = xl; x <= xh; x++) + for (y = yl; y <= yh; y++) + P_BlockThingsIterator(x, y, PIT_TNTExplode); + + // cause a quake -- P_StartQuake does not exist yet + epicenter.x = actor->x; + epicenter.y = actor->y; + epicenter.z = actor->z; + quake.intensity = 9*FRACUNIT; + quake.time = TICRATE/6; + quake.epicenter = &epicenter; + quake.radius = 512*FRACUNIT; + + if (locvar1) + { + P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 64, 0, actor->scale); + P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 96, FRACUNIT, actor->scale); + } + + actor->destscale *= 4; +} \ No newline at end of file diff --git a/src/p_map.c b/src/p_map.c index ffe6cf916..dbcb80f51 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -818,6 +818,41 @@ static boolean PIT_CheckThing(mobj_t *thing) } #endif + if (thing->type == MT_TNTBARREL && tmthing->player) + { + if (tmthing->momz < 0) + { + if (tmthing->z + tmthing->momz > thing->z + thing->height) + return true; + } + else + { + if (tmthing->z > thing->z + thing->height) + return true; + } + + if (tmthing->momz > 0) + { + if (tmthing->z + tmthing->height + tmthing->momz < thing->z) + return true; + } + else + { + if (tmthing->z + tmthing->height < thing->z) + return true; + } + + if ((tmthing->player->pflags & (PF_SPINNING | PF_GLIDING)) + || ((tmthing->player->pflags & PF_JUMPED) + && (!(tmthing->player->pflags & PF_NOJUMPDAMAGE) + || (tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY))) + || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2) + || ((tmthing->player->charflags & SF_STOMPDAMAGE || tmthing->player->pflags & PF_BOUNCING) + && (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height / 2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)) + || (((tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (tmthing->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (tmthing->player->pflags & PF_SHIELDABILITY))) + P_DamageMobj(thing, tmthing, tmthing, 1, 0); + } + if (tmthing->type == MT_FANG && thing->type == MT_FSGNB) { if (thing->z > tmthing->z + tmthing->height) diff --git a/src/p_mobj.c b/src/p_mobj.c index 649f4b330..d2b40e03b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9159,6 +9159,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) P_SetMobjState(overlay, S_OILLAMPFLARE); break; } + case MT_TNTBARREL: + mobj->momx = 1; //stack hack + break; default: break; } diff --git a/src/sounds.c b/src/sounds.c index cd5abd1f5..8c4c1e48c 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -195,6 +195,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bouncing"}, {"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork fired"}, {"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork hit"}, + {"bowl", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bowling"}, // Menu, interface {"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"}, @@ -373,7 +374,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k86", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Alarm"}, {"s3k87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"}, {"s3k88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic squeak"}, - {"s3k89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Advanced technology"}, + {"s3k89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Advanced tech"}, {"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"}, {"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"}, {"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Humming power"}, diff --git a/src/sounds.h b/src/sounds.h index fd1142aba..54318e215 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -261,6 +261,7 @@ typedef enum sfx_boingf, sfx_corkp, sfx_corkh, + sfx_bowl, // Menu, interface sfx_chchng, From ca4ab06abfd6bbdc7e4b7a06bdfad5f54e03c5bb Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 9 Jun 2019 12:27:09 +0200 Subject: [PATCH 06/51] Hardcoded wood debris --- src/dehacked.c | 4 ++++ src/hardware/hw_light.c | 1 + src/info.c | 30 ++++++++++++++++++++++++++++++ src/info.h | 5 +++++ src/p_enemy.c | 26 ++++++++++++++++++++++++++ 5 files changed, 66 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index bae63eb08..c83a4712f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2395,6 +2395,7 @@ static actionpointer_t actionpointers[] = {{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"}, {{A_DustDevilThink}, "A_DUSTDEVILTHINK"}, {{A_TNTExplode}, "A_TNTEXPLODE"}, + {{A_DebrisRandom}, "A_DEBRISRANDOM"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -7055,6 +7056,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_DUST3", "S_DUST4", + "S_WOODDEBRIS", + "S_ROCKSPAWN", "S_ROCKCRUMBLEA", @@ -7749,6 +7752,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_EXPLODE", // Robot Explosion "MT_UWEXPLODE", // Underwater Explosion "MT_DUST", + "MT_WOODDEBRIS", "MT_ROCKSPAWNER", "MT_FALLINGROCK", "MT_ROCKCRUMBLE1", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 1de293b54..bec9580c9 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -548,6 +548,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[SUPERSPARK_L], // SPR_BOM3 &lspr[NOLIGHT], // SPR_BOM4 &lspr[REDBALL_L], // SPR_BMNB + &lspr[NOLIGHT], // SPR_WDDB // Crumbly rocks &lspr[NOLIGHT], // SPR_ROIA diff --git a/src/info.c b/src/info.c index a513800a2..bce2328fc 100644 --- a/src/info.c +++ b/src/info.c @@ -443,6 +443,7 @@ char sprnames[NUMSPRITES + 1][5] = "BOM3", // Boss Explosion 2 "BOM4", // Underwater Explosion "BMNB", // Mine Explosion + "WDDB", // Wood Debris // Crumbly rocks "ROIA", @@ -3758,6 +3759,8 @@ state_t states[NUMSTATES] = {SPR_DUST, 2|FF_TRANS60, 3, {NULL}, 0, 0, S_DUST4}, // S_DUST3 {SPR_DUST, 3|FF_TRANS70, 2, {NULL}, 0, 0, S_NULL}, // S_DUST4 + {SPR_WDDB, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_WOODDEBRIS + {SPR_NULL, 0, 1, {A_RockSpawn}, 0, 0, S_ROCKSPAWN}, // S_ROCKSPAWN {SPR_ROIA, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 4, 2, S_NULL}, // S_ROCKCRUMBLEA @@ -18860,6 +18863,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_WOODDEBRIS + -1, // doomednum + S_WOODDEBRIS, // 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 + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_ROCKSPAWNER 1202, // doomednum S_ROCKSPAWN, // spawnstate diff --git a/src/info.h b/src/info.h index e2380a7ad..1b89ff748 100644 --- a/src/info.h +++ b/src/info.h @@ -253,6 +253,7 @@ void A_LookForBetter(); void A_Boss5BombExplode(); void A_DustDevilThink(); void A_TNTExplode(); +void A_DebrisRandom(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 @@ -676,6 +677,7 @@ typedef enum sprite SPR_BOM3, // Boss Explosion 2 SPR_BOM4, // Underwater Explosion SPR_BMNB, // Mine Explosion + SPR_WDDB, // Wood Debris // Crumbly rocks SPR_ROIA, @@ -3807,6 +3809,8 @@ typedef enum state S_DUST3, S_DUST4, + S_WOODDEBRIS, + S_ROCKSPAWN, S_ROCKCRUMBLEA, @@ -4521,6 +4525,7 @@ typedef enum mobj_type MT_EXPLODE, // Robot Explosion MT_UWEXPLODE, // Underwater Explosion MT_DUST, + MT_WOODDEBRIS, MT_ROCKSPAWNER, MT_FALLINGROCK, MT_ROCKCRUMBLE1, diff --git a/src/p_enemy.c b/src/p_enemy.c index 76ad8e234..f5b75dc0c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -282,6 +282,7 @@ void A_LookForBetter(mobj_t *actor); void A_Boss5BombExplode(mobj_t *actor); void A_DustDevilThink(mobj_t *actor); void A_TNTExplode(mobj_t *actor); +void A_DebrisRandom(mobj_t *actor); //for p_enemy.c // @@ -12778,4 +12779,29 @@ void A_TNTExplode(mobj_t *actor) } actor->destscale *= 4; +} + +// Function: A_DebrisRandom +// +// Description: Randomizes debris frame and movement. +// +// var1 = Frame range. +// var2 = unused +// +void A_DebrisRandom(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_DebrisRandom", actor)) + return; +#endif + + actor->frame |= P_RandomRange(0, locvar1); + var1 = 0; + var2 = 359; + A_ChangeAngleAbsolute(actor); + P_Thrust(actor, actor->angle, FRACUNIT * 2); + } \ No newline at end of file From 6df14492a5495af20390b9ee4de07e5ea86bf53b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 9 Jun 2019 13:48:07 +0200 Subject: [PATCH 07/51] Hardcoded train cameo --- src/dehacked.c | 12 ++++++ src/hardware/hw_light.c | 2 + src/info.c | 64 +++++++++++++++++++++++++++++ src/info.h | 15 +++++++ src/p_enemy.c | 89 +++++++++++++++++++++++++++++++++++++++++ src/sounds.c | 1 + src/sounds.h | 1 + 7 files changed, 184 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index c83a4712f..c51d9821b 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2396,6 +2396,8 @@ static actionpointer_t actionpointers[] = {{A_DustDevilThink}, "A_DUSTDEVILTHINK"}, {{A_TNTExplode}, "A_TNTEXPLODE"}, {{A_DebrisRandom}, "A_DEBRISRANDOM"}, + {{A_TrainCameo}, "A_TRAINCAMEO"}, + {{A_TrainCameo2}, "A_TRAINCAMEO2"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -5734,6 +5736,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARIDDUST2", "S_ARIDDUST3", + // Train cameo + "S_TRAINCAMEOSPAWNER_1", + "S_TRAINCAMEOSPAWNER_2", + "S_TRAINCAMEOSPAWNER_3", + "S_TRAINCAMEOSPAWNER_4", + "S_TRAINCAMEOSPAWNER_5", + "S_TRAINPUFFMAKER", + // Flame jet "S_FLAMEJETSTND", "S_FLAMEJETSTART", @@ -7430,6 +7440,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_DUSTDEVIL", "MT_DUSTLAYER", "MT_ARIDDUST", + "MT_TRAINCAMEOSPAWNER", + "MT_TRAINSEG", // Red Volcano Scenery "MT_FLAMEJET", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index bec9580c9..52d5ec448 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -356,6 +356,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_REMT &lspr[NOLIGHT], // SPR_TAZD &lspr[NOLIGHT], // SPR_ADST + &lspr[NOLIGHT], // SPR_TRAE + &lspr[NOLIGHT], // SPR_TRAI // Red Volcano Scenery &lspr[REDBALL_L], // SPR_FLME diff --git a/src/info.c b/src/info.c index bce2328fc..18de789ec 100644 --- a/src/info.c +++ b/src/info.c @@ -251,6 +251,8 @@ char sprnames[NUMSPRITES + 1][5] = "REMT", // TNT proximity shell "TAZD", // Dust devil "ADST", // Arid dust + "TRAE", // Train cameo locomotive + "TRAI", // Train cameo wagon // Red Volcano Scenery "FLME", // Flame jet @@ -2373,6 +2375,14 @@ state_t states[NUMSTATES] = {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 + // Train cameo + {SPR_NULL, 0, -1, {NULL}, 0, 0, S_TRAINCAMEOSPAWNER_2}, // S_TRAINCAMEOSPAWNER_1 + {SPR_NULL, 0, 14, {A_TrainCameo}, 20, 18, S_TRAINCAMEOSPAWNER_3}, // S_TRAINCAMEOSPAWNER_2 + {SPR_NULL, 0, 1, {A_Repeat}, 1, 0, S_TRAINCAMEOSPAWNER_4}, // S_TRAINCAMEOSPAWNER_3 + {SPR_NULL, 0, 18, {A_TrainCameo2}, 20, 44, S_TRAINCAMEOSPAWNER_5}, // S_TRAINCAMEOSPAWNER_4 + {SPR_NULL, 0, 1, {A_Repeat}, 5, S_TRAINCAMEOSPAWNER_4, S_NULL}, // S_TRAINCAMEOSPAWNER_5 + {SPR_NULL, 0, 2, {A_SmokeTrailer}, MT_SMOKE, 0, S_TRAINPUFFMAKER}, // S_TRAINPUFFMAKER + // 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 @@ -11638,6 +11648,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_TRAINCAMEOSPAWNER + 1222, // doomednum + S_TRAINCAMEOSPAWNER_1, // 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 + 28*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_TRAINSEG + -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 + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_FLAMEJET 1300, // doomednum S_FLAMEJETSTND, // spawnstate diff --git a/src/info.h b/src/info.h index 1b89ff748..f0ca27e10 100644 --- a/src/info.h +++ b/src/info.h @@ -254,6 +254,9 @@ void A_Boss5BombExplode(); void A_DustDevilThink(); void A_TNTExplode(); void A_DebrisRandom(); +void A_TrainCameo(); +void A_TrainCameo2(); + // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 @@ -485,6 +488,8 @@ typedef enum sprite SPR_REMT, // TNT proximity shell SPR_TAZD, // Dust devil SPR_ADST, // Arid dust + SPR_TRAE, // Train cameo locomotive + SPR_TRAI, // Train cameo wagon // Red Volcano Scenery SPR_FLME, // Flame jet @@ -2487,6 +2492,14 @@ typedef enum state S_ARIDDUST2, S_ARIDDUST3, + // Train cameo + S_TRAINCAMEOSPAWNER_1, + S_TRAINCAMEOSPAWNER_2, + S_TRAINCAMEOSPAWNER_3, + S_TRAINCAMEOSPAWNER_4, + S_TRAINCAMEOSPAWNER_5, + S_TRAINPUFFMAKER, + // Flame jet S_FLAMEJETSTND, S_FLAMEJETSTART, @@ -4203,6 +4216,8 @@ typedef enum mobj_type MT_DUSTDEVIL, MT_DUSTLAYER, MT_ARIDDUST, + MT_TRAINCAMEOSPAWNER, + MT_TRAINSEG, // Red Volcano Scenery MT_FLAMEJET, diff --git a/src/p_enemy.c b/src/p_enemy.c index f5b75dc0c..be4701009 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -283,6 +283,8 @@ void A_Boss5BombExplode(mobj_t *actor); void A_DustDevilThink(mobj_t *actor); void A_TNTExplode(mobj_t *actor); void A_DebrisRandom(mobj_t *actor); +void A_TrainCameo(mobj_t *actor); +void A_TrainCameo2(mobj_t *actor); //for p_enemy.c // @@ -12803,5 +12805,92 @@ void A_DebrisRandom(mobj_t *actor) var2 = 359; A_ChangeAngleAbsolute(actor); P_Thrust(actor, actor->angle, FRACUNIT * 2); +} +static mobj_t *P_TrainSeg(mobj_t *src, fixed_t x, fixed_t y, fixed_t z, angle_t ang, spritenum_t spr, UINT32 frame) +{ + mobj_t *s = P_SpawnMobj(x, y, z, MT_TRAINSEG); + s->fuse = 16*TICRATE; + s->sprite = spr; + s->frame = frame|FF_PAPERSPRITE; + s->angle = ang; + P_Thrust(s, src->angle, 7*FRACUNIT); + return s; +} + +// Function: A_TrainCameo +// +// Description: Sets up train cameo locomotive. +// +// var1 = Train width. +// var2 = Train length. +// +void A_TrainCameo(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t x = actor->x; + fixed_t y = actor->y; + fixed_t z = actor->z; + angle_t ang = actor->angle; + mobj_t *m; + spritenum_t spr = SPR_TRAE; + fixed_t span = locvar1*FRACUNIT; + fixed_t len = locvar2*FRACUNIT; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_TrainCameo", actor)) + return; +#endif + + //Spawn sides. + P_TrainSeg(actor, x, y + span, z, ang, spr, 0); + P_TrainSeg(actor, x, y - span, z, ang, spr, 0); + + //Center. + P_TrainSeg(actor, x, y, z, ang, spr, 1); + + //Front and back. + P_TrainSeg(actor, x + len, y, z, ang + ANGLE_90, spr, 2); + P_TrainSeg(actor, x - len, y, z, ang + ANGLE_90, spr, 2); + + //Smoke spawner. + m = P_TrainSeg(actor, x - (20 * FRACUNIT), y, z + (30 * FRACUNIT), ang + ANGLE_90, spr, 0); + P_SetMobjState(m, S_TRAINPUFFMAKER); +} + +// Function: A_TrainCameo2 +// +// Description: Sets up train cameo wagon. +// +// var1 = Train width. +// var2 = Train length. +// +void A_TrainCameo2(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t x = actor->x; + fixed_t y = actor->y; + fixed_t z = actor->z; + angle_t ang = actor->angle; + spritenum_t spr = SPR_TRAI; + fixed_t span = locvar1*FRACUNIT; + fixed_t len = locvar2*FRACUNIT; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_TrainCameo2", actor)) + return; +#endif + + //Spawn sides. + P_TrainSeg(actor, x, y + span, z, ang, spr, 0); + P_TrainSeg(actor, x, y - span, z, ang, spr, 0); + + //Center. + P_TrainSeg(actor, x, y, z, ang, spr, 1); + + //Front and back. + P_TrainSeg(actor, x + len, y, z, ang + ANGLE_90, spr, 2); + P_TrainSeg(actor, x - len, y, z, ang + ANGLE_90, spr, 2); } \ No newline at end of file diff --git a/src/sounds.c b/src/sounds.c index 8c4c1e48c..3139ba1e3 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -196,6 +196,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork fired"}, {"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork hit"}, {"bowl", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bowling"}, + {"chuchu", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Train horn"}, // Menu, interface {"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"}, diff --git a/src/sounds.h b/src/sounds.h index 54318e215..489e28826 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -262,6 +262,7 @@ typedef enum sfx_corkp, sfx_corkh, sfx_bowl, + sfx_chuchu, // Menu, interface sfx_chchng, From 3a16a7d7d4ddfcf68381bea9d37765648150d432 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 9 Jun 2019 17:16:07 +0200 Subject: [PATCH 08/51] Hardcoded train dust and steam spawner --- src/dehacked.c | 6 +++++ src/hardware/hw_light.c | 1 + src/info.c | 58 +++++++++++++++++++++++++++++++++++++++++ src/info.h | 7 +++++ src/p_mobj.c | 27 +++++++++++++++++++ 5 files changed, 99 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index c51d9821b..db1a24a12 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5744,6 +5744,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TRAINCAMEOSPAWNER_5", "S_TRAINPUFFMAKER", + // Train + "S_TRAINDUST", + "S_TRAINSTEAM", + // Flame jet "S_FLAMEJETSTND", "S_FLAMEJETSTART", @@ -7442,6 +7446,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_ARIDDUST", "MT_TRAINCAMEOSPAWNER", "MT_TRAINSEG", + "MT_TRAINDUSTSPAWNER", + "MT_TRAINSTEAMSPAWNER", // Red Volcano Scenery "MT_FLAMEJET", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 52d5ec448..97772d4be 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -358,6 +358,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_ADST &lspr[NOLIGHT], // SPR_TRAE &lspr[NOLIGHT], // SPR_TRAI + &lspr[NOLIGHT], // SPR_STEA // Red Volcano Scenery &lspr[REDBALL_L], // SPR_FLME diff --git a/src/info.c b/src/info.c index 18de789ec..6fcdbf753 100644 --- a/src/info.c +++ b/src/info.c @@ -253,6 +253,7 @@ char sprnames[NUMSPRITES + 1][5] = "ADST", // Arid dust "TRAE", // Train cameo locomotive "TRAI", // Train cameo wagon + "STEA", // Train steam // Red Volcano Scenery "FLME", // Flame jet @@ -2383,6 +2384,9 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 1, {A_Repeat}, 5, S_TRAINCAMEOSPAWNER_4, S_NULL}, // S_TRAINCAMEOSPAWNER_5 {SPR_NULL, 0, 2, {A_SmokeTrailer}, MT_SMOKE, 0, S_TRAINPUFFMAKER}, // S_TRAINPUFFMAKER + {SPR_ADST, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_TRAINDUST + {SPR_STEA, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_TRAINSTEAM + // 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 @@ -11702,6 +11706,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_TRAINDUSTSPAWNER + 1223, // 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 + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_TRAINSTEAMSPAWNER + 1224, // 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 + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags + S_NULL // raisestate + }, + { // MT_FLAMEJET 1300, // doomednum S_FLAMEJETSTND, // spawnstate diff --git a/src/info.h b/src/info.h index f0ca27e10..f1439fb2e 100644 --- a/src/info.h +++ b/src/info.h @@ -490,6 +490,7 @@ typedef enum sprite SPR_ADST, // Arid dust SPR_TRAE, // Train cameo locomotive SPR_TRAI, // Train cameo wagon + SPR_STEA, // Train steam // Red Volcano Scenery SPR_FLME, // Flame jet @@ -2500,6 +2501,10 @@ typedef enum state S_TRAINCAMEOSPAWNER_5, S_TRAINPUFFMAKER, + // Train + S_TRAINDUST, + S_TRAINSTEAM, + // Flame jet S_FLAMEJETSTND, S_FLAMEJETSTART, @@ -4218,6 +4223,8 @@ typedef enum mobj_type MT_ARIDDUST, MT_TRAINCAMEOSPAWNER, MT_TRAINSEG, + MT_TRAINDUSTSPAWNER, + MT_TRAINSTEAMSPAWNER, // Red Volcano Scenery MT_FLAMEJET, diff --git a/src/p_mobj.c b/src/p_mobj.c index d2b40e03b..10f4c1bc1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8412,6 +8412,33 @@ void P_MobjThinker(mobj_t *mobj) mobj->flags2 |= MF2_DONTDRAW; } break; + case MT_TRAINDUSTSPAWNER: + if (leveltime % 5 == 0) { + mobj_t *traindust = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PARTICLE); + traindust->flags = MF_SCENERY; + P_SetMobjState(traindust, S_TRAINDUST); + traindust->frame = P_RandomRange(0, 8) | FF_TRANS90; + traindust->angle = mobj->angle; + traindust->tics = TICRATE * 4; + traindust->destscale = FRACUNIT * 64; + traindust->scalespeed = FRACUNIT / 24; + P_SetScale(traindust, FRACUNIT * 6); + } + break; + case MT_TRAINSTEAMSPAWNER: + if (leveltime % 5 == 0) { + mobj_t *steam = P_SpawnMobj(mobj->x + FRACUNIT*P_SignedRandom() / 2, mobj->y + FRACUNIT*P_SignedRandom() / 2, mobj->z, MT_PARTICLE); + P_SetMobjState(steam, S_TRAINSTEAM); + steam->frame = P_RandomRange(0, 1) | FF_TRANS90; + steam->tics = TICRATE * 8; + steam->destscale = FRACUNIT * 64; + steam->scalespeed = FRACUNIT / 8; + P_SetScale(steam, FRACUNIT * 16); + steam->momx = P_SignedRandom() * 32; + steam->momy = -64 * FRACUNIT; + steam->momz = 2 * FRACUNIT; + } + break; case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) { From 98ea229680906158572ee53930de23a6588aead1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 10 Jun 2019 13:58:16 +0200 Subject: [PATCH 09/51] Hardcoded the Canarivore --- src/dehacked.c | 25 +++++++++++++ src/hardware/hw_light.c | 2 ++ src/info.c | 79 +++++++++++++++++++++++++++++++++++++++++ src/info.h | 28 ++++++++++++++- src/p_enemy.c | 36 +++++++++++++++---- src/p_inter.c | 10 ++++++ src/p_mobj.c | 28 +++++++++++++++ src/sounds.c | 2 +- 8 files changed, 201 insertions(+), 9 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index db1a24a12..6a3aae290 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2398,6 +2398,7 @@ static actionpointer_t actionpointers[] = {{A_DebrisRandom}, "A_DEBRISRANDOM"}, {{A_TrainCameo}, "A_TRAINCAMEO"}, {{A_TrainCameo2}, "A_TRAINCAMEO2"}, + {{A_CanarivoreGas}, "A_CANARIVOREGAS"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -4498,6 +4499,28 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_UNIDUS_RUN", "S_UNIDUS_BALL", + // Canarivore + "S_CANARIVORE_LOOK", + "S_CANARIVORE_AWAKEN1", + "S_CANARIVORE_AWAKEN2", + "S_CANARIVORE_AWAKEN3", + "S_CANARIVORE_GAS1", + "S_CANARIVORE_GAS2", + "S_CANARIVORE_GAS3", + "S_CANARIVORE_GAS4", + "S_CANARIVORE_GAS5", + "S_CANARIVORE_GASREPEAT", + "S_CANARIVORE_CLOSE1", + "S_CANARIVORE_CLOSE2", + "S_CANARIVOREGAS_1", + "S_CANARIVOREGAS_2", + "S_CANARIVOREGAS_3", + "S_CANARIVOREGAS_4", + "S_CANARIVOREGAS_5", + "S_CANARIVOREGAS_6", + "S_CANARIVOREGAS_7", + "S_CANARIVOREGAS_8", + // Boss Explosion "S_BOSSEXPLODE", @@ -7140,6 +7163,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_YELLOWSHELL", // Spring Shell (yellow) "MT_UNIDUS", // Unidus "MT_UNIBALL", // Unidus Ball + "MT_CANARIVORE", // Canarivore + "MT_CANARIVORE_GAS", // Canarivore gas // Generic Boss Items "MT_BOSSEXPLODE", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 97772d4be..4c4e369e6 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -175,6 +175,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_MNUS &lspr[NOLIGHT], // SPR_SSHL &lspr[NOLIGHT], // SPR_UNID + &lspr[NOLIGHT], // SPR_CANA + &lspr[NOLIGHT], // SPR_CANG // Generic Boos Items &lspr[JETLIGHT_L], // SPR_JETF // Boss jet fumes diff --git a/src/info.c b/src/info.c index 6fcdbf753..6f6ad140a 100644 --- a/src/info.c +++ b/src/info.c @@ -63,6 +63,8 @@ char sprnames[NUMSPRITES + 1][5] = "MNUS", // Minus "SSHL", // Spring Shell "UNID", // Unidus + "CANA", // Canarivore + "CANG", // Canarivore gas // Generic Boss Items "JETF", // Boss jet fumes @@ -1110,6 +1112,29 @@ state_t states[NUMSTATES] = {SPR_UNID, 0, 1, {A_Chase}, 0, 0, S_UNIDUS_RUN }, // S_UNIDUS_RUN {SPR_UNID, 1, 1, {A_UnidusBall}, 1, 0, S_UNIDUS_BALL}, // S_UNIDUS_BALL + // Canarivore + {SPR_CANA, 0, 5, {A_Look}, 1200*FRACUNIT+1, 1, S_CANARIVORE_LOOK}, // S_CANARIVORE_LOOK + {SPR_CANA, 0, 3, {A_PlaySound}, sfx_s3k76, 1, S_CANARIVORE_AWAKEN2}, // S_CANARIVORE_AWAKEN1 + {SPR_CANA, 1, 5, {NULL}, 0, 0, S_CANARIVORE_AWAKEN3}, // S_CANARIVORE_AWAKEN2 + {SPR_CANA, 2, 8, {NULL}, 0, 0, S_CANARIVORE_GAS1}, // S_CANARIVORE_AWAKEN3 + {SPR_CANA, 2, 15, {A_PlaySound}, sfx_s3k93, 1, S_CANARIVORE_GAS2}, // S_CANARIVORE_GAS1 + {SPR_CANA, 1, 4, {NULL}, 0, 0, S_CANARIVORE_GAS3}, // S_CANARIVORE_GAS2 + {SPR_CANA, 2, 0, {A_PlaySound}, sfx_s3k97, 1, S_CANARIVORE_GAS4}, // S_CANARIVORE_GAS3 + {SPR_CANA, 2, 5, {A_CanarivoreGas}, MT_CANARIVORE_GAS, 0, S_CANARIVORE_GAS5}, // S_CANARIVORE_GAS4 + {SPR_CANA, 1, 5, {NULL}, 0, 0, S_CANARIVORE_GASREPEAT}, // S_CANARIVORE_GAS5 + {SPR_CANA, 2, 0, {A_Repeat}, 6, S_CANARIVORE_GAS4, S_CANARIVORE_CLOSE1}, // S_CANARIVORE_GASREPEAT + {SPR_CANA, 1, 8, {NULL}, 0, 0, S_CANARIVORE_CLOSE2}, // S_CANARIVORE_CLOSE1 + {SPR_CANA, 0, 90, {NULL}, sfx_s3k5d, 1, S_CANARIVORE_LOOK}, // S_CANARIVORE_CLOSE2 + + {SPR_CANG, 0|FF_TRANS90, 2, {NULL}, 0, 0, S_CANARIVOREGAS_2}, // S_CANARIVOREGAS_1 + {SPR_CANG, 0|FF_TRANS30, 2*TICRATE, {A_SetRandomTics}, 2, TICRATE, S_CANARIVOREGAS_3}, // S_CANARIVOREGAS_2 + {SPR_CANG, 0|FF_TRANS40, 10, {NULL}, 0, 0, S_CANARIVOREGAS_4}, // S_CANARIVOREGAS_3 + {SPR_CANG, 0|FF_TRANS50, 10, {NULL}, 0, 0, S_CANARIVOREGAS_5}, // S_CANARIVOREGAS_4 + {SPR_CANG, 0|FF_TRANS60, 10, {NULL}, 0, 0, S_CANARIVOREGAS_6}, // S_CANARIVOREGAS_5 + {SPR_CANG, 0|FF_TRANS70, 10, {NULL}, 0, 0, S_CANARIVOREGAS_7}, // S_CANARIVOREGAS_6 + {SPR_CANG, 0|FF_TRANS80, 10, {NULL}, 0, 0, S_CANARIVOREGAS_8}, // S_CANARIVOREGAS_7 + {SPR_CANG, 0|FF_TRANS90, 10, {NULL}, 0, 0, S_NULL}, // S_CANARIVOREGAS_8 + // Boss Explosion {SPR_BOM2, FF_FULLBRIGHT|FF_ANIMATE, (5*7), {NULL}, 6, 5, S_NULL}, // S_BOSSEXPLODE @@ -4800,6 +4825,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_CANARIVORE + 134, // doomednum + S_CANARIVORE_LOOK, // spawnstate + 1, // spawnhealth + S_CANARIVORE_AWAKEN1, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_XPLD_FLICKY, // deathstate + S_NULL, // xdeathstate + sfx_pop, // deathsound + 0, // speed + 12*FRACUNIT, // radius + 80*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_SPAWNCEILING|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_CANARIVORE_GAS + -1, // doomednum + S_CANARIVOREGAS_1, // 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_s3k5d, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_SPECIAL, // flags + S_NULL // raisestate + }, + { // MT_BOSSEXPLODE -1, // doomednum S_BOSSEXPLODE, // spawnstate diff --git a/src/info.h b/src/info.h index f1439fb2e..44f1bea1f 100644 --- a/src/info.h +++ b/src/info.h @@ -256,7 +256,7 @@ void A_TNTExplode(); void A_DebrisRandom(); void A_TrainCameo(); void A_TrainCameo2(); - +void A_CanarivoreGas(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 @@ -300,6 +300,8 @@ typedef enum sprite SPR_MNUS, // Minus SPR_SSHL, // Spring Shell SPR_UNID, // Unidus + SPR_CANA, // Canarivore + SPR_CANG, // Canarivore gas // Generic Boss Items SPR_JETF, // Boss jet fumes @@ -1255,6 +1257,28 @@ typedef enum state S_UNIDUS_RUN, S_UNIDUS_BALL, + // Canarivore + S_CANARIVORE_LOOK, + S_CANARIVORE_AWAKEN1, + S_CANARIVORE_AWAKEN2, + S_CANARIVORE_AWAKEN3, + S_CANARIVORE_GAS1, + S_CANARIVORE_GAS2, + S_CANARIVORE_GAS3, + S_CANARIVORE_GAS4, + S_CANARIVORE_GAS5, + S_CANARIVORE_GASREPEAT, + S_CANARIVORE_CLOSE1, + S_CANARIVORE_CLOSE2, + S_CANARIVOREGAS_1, + S_CANARIVOREGAS_2, + S_CANARIVOREGAS_3, + S_CANARIVOREGAS_4, + S_CANARIVOREGAS_5, + S_CANARIVOREGAS_6, + S_CANARIVOREGAS_7, + S_CANARIVOREGAS_8, + // Boss Explosion S_BOSSEXPLODE, @@ -3917,6 +3941,8 @@ typedef enum mobj_type MT_YELLOWSHELL, // Spring Shell (yellow) MT_UNIDUS, // Unidus MT_UNIBALL, // Unidus Ball + MT_CANARIVORE, // Canarivore + MT_CANARIVORE_GAS, // Canarivore gas // Generic Boss Items MT_BOSSEXPLODE, diff --git a/src/p_enemy.c b/src/p_enemy.c index be4701009..3719d8b6c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -285,6 +285,7 @@ void A_TNTExplode(mobj_t *actor); void A_DebrisRandom(mobj_t *actor); void A_TrainCameo(mobj_t *actor); void A_TrainCameo2(mobj_t *actor); +void A_CanarivoreGas(mobj_t *actor); //for p_enemy.c // @@ -12457,9 +12458,10 @@ void A_LookForBetter(mobj_t *actor) * \param z Center Z coordinates. * \param radius Radius. * \param speed Additional thrust on particles. - * \param scale Scale. + * \param initscale Initial scale when spawning. + * \param scale "Default" scale. */ -static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t speed, fixed_t scale) +static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t speed, fixed_t initscale, fixed_t scale) { angle_t ang = FixedAngle(FixedDiv(360*FRACUNIT, div*FRACUNIT)); //(ANGLE_180/div)*2; UINT32 i; @@ -12480,7 +12482,7 @@ static void P_DustRing(mobjtype_t mobjtype, UINT32 div, fixed_t x, fixed_t y, fi ); dust->angle = ang*i + ANGLE_90; - P_SetScale(dust, scale); + P_SetScale(dust, FixedMul(initscale, scale)); dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale); dust->scalespeed = scale/24; P_Thrust(dust, ang*i, speed + FixedMul(P_RandomFixed(), scale)); @@ -12513,8 +12515,8 @@ void A_Boss5BombExplode(mobj_t *actor) if (actor->target) P_RadiusAttack(actor, actor->target, 7*actor->radius, 0); - P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 2*actor->radius, 0, actor->scale); - P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, actor->scale); + P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 2*actor->radius, 0, FRACUNIT, actor->scale); + P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale); //P_StartQuake(9*actor->scale, TICRATE/6, {actor->x, actor->y, actor->z}, 20*actor->radius); // the above does not exist, so we set the quake values directly instead quake.intensity = 9*actor->scale; @@ -12776,8 +12778,8 @@ void A_TNTExplode(mobj_t *actor) if (locvar1) { - P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 64, 0, actor->scale); - P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 96, FRACUNIT, actor->scale); + P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 64, 0, FRACUNIT, actor->scale); + P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 96, FRACUNIT, FRACUNIT, actor->scale); } actor->destscale *= 4; @@ -12893,4 +12895,24 @@ void A_TrainCameo2(mobj_t *actor) //Front and back. P_TrainSeg(actor, x + len, y, z, ang + ANGLE_90, spr, 2); P_TrainSeg(actor, x - len, y, z, ang + ANGLE_90, spr, 2); +} + +// Function: A_CanarivoreGas +// +// Description: Releases gas clouds. Used by the Canarivore. +// +// var1 = Mobj type. +// var2 = Unused +// +void A_CanarivoreGas(mobj_t *actor) +{ + INT32 locvar1 = var1; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_CanarivoreGas", actor)) + return; +#endif + + P_DustRing(locvar1, 4, actor->x, actor->y, actor->z + actor->height / 5, 18, 0, FRACUNIT/10, actor->scale); + P_DustRing(locvar1, 6, actor->x, actor->y, actor->z + actor->height / 5, 28, FRACUNIT, FRACUNIT/10, actor->scale); } \ No newline at end of file diff --git a/src/p_inter.c b/src/p_inter.c index 68f1782c5..aed63b208 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1699,6 +1699,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; + case MT_CANARIVORE_GAS: + // if player and gas touch, attach gas to player (overriding any gas that already attached) and apply slowdown effect + P_TeleportMove(special, toucher->x - toucher->momx / 2, toucher->y - toucher->momy / 2, toucher->z - toucher->momz / 2); + toucher->momx = FixedMul(toucher->momx, 50 * FRACUNIT / 51); + toucher->momy = FixedMul(toucher->momy, 50 * FRACUNIT / 51); + special->momx = toucher->momx; + special->momy = toucher->momy; + special->momz = toucher->momz; + return; + default: // SOC or script pickup if (player->bot) return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 10f4c1bc1..e3276fde4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8439,6 +8439,34 @@ void P_MobjThinker(mobj_t *mobj) steam->momz = 2 * FRACUNIT; } break; + case MT_CANARIVORE_GAS: + { + fixed_t momz; + + if (mobj->flags2 & MF2_AMBUSH) + { + mobj->momx = FixedMul(mobj->momx, 50 * FRACUNIT / 51); + mobj->momy = FixedMul(mobj->momy, 50 * FRACUNIT / 51); + break; + } + + if (mobj->eflags & MFE_VERTICALFLIP) + { + if ((mobj->z + mobj->height + mobj->momz) <= mobj->ceilingz) + break; + } + else + { + if ((mobj->z + mobj->momz) >= mobj->floorz) + break; + } + + momz = abs(mobj->momz); + if (R_PointToDist2(0, 0, mobj->momx, mobj->momy) < momz) + P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), momz); + mobj->flags2 |= MF2_AMBUSH; + break; + } case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) { diff --git a/src/sounds.c b/src/sounds.c index 3139ba1e3..84b2c8a0c 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -385,7 +385,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"}, {"s3k91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Closed"}, {"s3k92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ghost"}, - {"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rebuilding"}, + {"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gas release"}, {"s3k94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"}, {"s3k95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lava burst"}, {"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling object"}, From 4d0b0f84b1b2bc35ab47505797773e297e60f272 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 10 Jun 2019 14:10:37 +0200 Subject: [PATCH 10/51] Pushables that are also vulnerable no longer block crushers (because they die anyway). This allows us to make TNT barrels pushable again. --- src/info.c | 2 +- src/p_map.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index 6f6ad140a..659e883a5 100644 --- a/src/info.c +++ b/src/info.c @@ -11619,7 +11619,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_s3k8d, // activesound - MF_SOLID|MF_SHOOTABLE|MF_ENEMY, // flags + MF_SOLID|MF_SHOOTABLE|MF_ENEMY|MF_PUSHABLE, // flags S_NULL // raisestate }, diff --git a/src/p_map.c b/src/p_map.c index dbcb80f51..ca4548d0b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3894,6 +3894,8 @@ static boolean nofit; static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) { mobj_t *killer = NULL; + //If a thing is both pushable and vulnerable, it doesn't block the crusher because it gets killed. + boolean immunepushable = ((thing->flags & (MF_PUSHABLE | MF_SHOOTABLE)) == MF_PUSHABLE); if (P_ThingHeightClip(thing)) { @@ -3912,7 +3914,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) // just be blocked by another object - check if it's really a ceiling! if (thing->z + thing->height > thing->ceilingz && thing->z <= thing->ceilingz) { - if (thing->flags & MF_PUSHABLE && thing->z + thing->height > thing->subsector->sector->ceilingheight) + if (immunepushable && thing->z + thing->height > thing->subsector->sector->ceilingheight) { //Thing is a pushable and blocks the moving ceiling nofit = true; @@ -3920,7 +3922,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) } //Check FOFs in the sector - if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE)) + if (thing->subsector->sector->ffloors && (realcrush || immunepushable)) { ffloor_t *rover; fixed_t topheight, bottomheight; @@ -3947,7 +3949,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) delta2 = thingtop - (bottomheight + topheight)/2; if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) { - if (thing->flags & MF_PUSHABLE) + if (immunepushable) { //FOF is blocked by pushable nofit = true; From b98de5d362a64d005d661465020901994d12316d Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 10 Jun 2019 16:09:15 +0200 Subject: [PATCH 11/51] Hardcoded the new BASH behavior (there's still a bug lurking somewhere) --- src/dehacked.c | 12 ++- src/info.c | 29 +++---- src/info.h | 12 ++- src/p_enemy.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++++ src/p_map.c | 11 +++ 5 files changed, 249 insertions(+), 31 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 6a3aae290..a76e7c9f0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2265,6 +2265,9 @@ static actionpointer_t actionpointers[] = {{A_CrushclawLaunch}, "A_CRUSHCLAWLAUNCH"}, {{A_VultureVtol}, "A_VULTUREVTOL"}, {{A_VultureCheck}, "A_VULTURECHECK"}, + {{A_VultureHover}, "A_VULTUREHOVER"}, + {{A_VultureBlast}, "A_VULTUREBLAST"}, + {{A_VultureFly}, "A_VULTUREFLY"}, {{A_SkimChase}, "A_SKIMCHASE"}, {{A_1upThinker}, "A_1UPTHINKER"}, {{A_SkullAttack}, "A_SKULLATTACK"}, @@ -4386,15 +4389,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Vulture "S_VULTURE_STND", - "S_VULTURE_VTOL1", - "S_VULTURE_VTOL2", - "S_VULTURE_VTOL3", - "S_VULTURE_VTOL4", + "S_VULTURE_DRIFT", "S_VULTURE_ZOOM1", "S_VULTURE_ZOOM2", - "S_VULTURE_ZOOM3", - "S_VULTURE_ZOOM4", - "S_VULTURE_ZOOM5", + "S_VULTURE_STUNNED", // Pointy "S_POINTY1", diff --git a/src/info.c b/src/info.c index 659e883a5..cc0ad09f7 100644 --- a/src/info.c +++ b/src/info.c @@ -996,16 +996,11 @@ state_t states[NUMSTATES] = {SPR_SNLR, 0, 1, {A_SnailerThink}, 0, 0, S_SNAILER1}, // S_SNAILER1 // Vulture - {SPR_VLTR, 4, 35, {A_Look}, 1, 0, S_VULTURE_STND}, // S_VULTURE_STND - {SPR_VLTR, 4, 1, {A_VultureVtol}, 0, 0, S_VULTURE_VTOL2}, // S_VULTURE_VTOL1 - {SPR_VLTR, 5, 1, {A_VultureVtol}, 0, 0, S_VULTURE_VTOL3}, // S_VULTURE_VTOL2 - {SPR_VLTR, 6, 1, {A_VultureVtol}, 0, 0, S_VULTURE_VTOL4}, // S_VULTURE_VTOL3 - {SPR_VLTR, 7, 1, {A_VultureVtol}, 0, 0, S_VULTURE_VTOL1}, // S_VULTURE_VTOL4 - {SPR_VLTR, 0, 1, {A_Thrust}, 30, 1, S_VULTURE_ZOOM2}, // S_VULTURE_ZOOM1 - {SPR_VLTR, 0, 1, {A_VultureCheck}, 0, 0, S_VULTURE_ZOOM3}, // S_VULTURE_ZOOM2 - {SPR_VLTR, 1, 1, {A_VultureCheck}, 0, 0, S_VULTURE_ZOOM4}, // S_VULTURE_ZOOM3 - {SPR_VLTR, 2, 1, {A_VultureCheck}, 0, 0, S_VULTURE_ZOOM5}, // S_VULTURE_ZOOM4 - {SPR_VLTR, 3, 1, {A_VultureCheck}, 0, 0, S_VULTURE_ZOOM2}, // S_VULTURE_ZOOM5 + {SPR_VLTR, 4, 35, {A_Look}, 1, 0, S_VULTURE_STND}, // S_VULTURE_STND + {SPR_VLTR, 4, 3, {A_VultureHover}, 0, 0, S_VULTURE_DRIFT}, // S_VULTURE_DRIFT + {SPR_VLTR, 0, 6, {A_VultureBlast}, 0, 0, S_VULTURE_ZOOM2}, // S_VULTURE_ZOOM1 + {SPR_VLTR, 0, 3, {A_VultureFly}, 0, 0, S_VULTURE_ZOOM2}, // S_VULTURE_ZOOM2 + {SPR_VLTR, 0, 3*TICRATE, {NULL}, 0, 0, S_VULTURE_DRIFT}, // S_VULTURE_STUNNED // Pointy {SPR_PNTY, 0, 1, {A_PointyThink}, 0, 0, S_POINTY1}, // S_POINTY1 @@ -4451,26 +4446,26 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 115, // doomednum S_VULTURE_STND, // spawnstate 1, // spawnhealth - S_VULTURE_VTOL1,// seestate + S_VULTURE_DRIFT,// seestate sfx_None, // seesound - 2, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate + TICRATE/2, // reactiontime + sfx_s3k60, // attacksound + S_VULTURE_STUNNED, // painstate S_NULL, // painchance - sfx_None, // painsound + sfx_s3k96, // painsound S_NULL, // meleestate S_VULTURE_ZOOM1,// missilestate S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - 3, // speed + 5, // speed 12*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset TICRATE, // mass 0, // damage sfx_jet, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY, // flags + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_SLIDEME, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 44f1bea1f..6e544d2d6 100644 --- a/src/info.h +++ b/src/info.h @@ -115,6 +115,9 @@ void A_CrushclawAim(); void A_CrushclawLaunch(); void A_VultureVtol(); void A_VultureCheck(); +void A_VultureHover(); +void A_VultureBlast(); +void A_VultureFly(); void A_SkimChase(); void A_SkullAttack(); void A_LobShot(); @@ -1144,15 +1147,10 @@ typedef enum state // Vulture S_VULTURE_STND, - S_VULTURE_VTOL1, - S_VULTURE_VTOL2, - S_VULTURE_VTOL3, - S_VULTURE_VTOL4, + S_VULTURE_DRIFT, S_VULTURE_ZOOM1, S_VULTURE_ZOOM2, - S_VULTURE_ZOOM3, - S_VULTURE_ZOOM4, - S_VULTURE_ZOOM5, + S_VULTURE_STUNNED, // Pointy S_POINTY1, diff --git a/src/p_enemy.c b/src/p_enemy.c index 3719d8b6c..450cba37a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -79,6 +79,9 @@ void A_CrushclawAim(mobj_t *actor); void A_CrushclawLaunch(mobj_t *actor); void A_VultureVtol(mobj_t *actor); void A_VultureCheck(mobj_t *actor); +void A_VultureHover(mobj_t *actor); +void A_VultureBlast(mobj_t *actor); +void A_VultureFly(mobj_t *actor); void A_SkimChase(mobj_t *actor); void A_FaceTarget(mobj_t *actor); void A_FaceTracer(mobj_t *actor); @@ -2301,6 +2304,219 @@ void A_VultureCheck(mobj_t *actor) } } +static void P_VultureHoverParticle(mobj_t *actor) +{ + fixed_t fdist = actor->z - P_FloorzAtPos(actor->x, actor->y, actor->z, actor->height); + + if (fdist < 128*FRACUNIT) + { + mobj_t *dust; + UINT8 i; + angle_t angle = (leveltime % 2)*ANGLE_45/2; + + for (i = 0; i <= 7; i++) + { + angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t px = actor->x + FixedMul(fdist + 64*FRACUNIT, FINECOSINE(fa)); + fixed_t py = actor->y + FixedMul(fdist + 64*FRACUNIT, FINESINE(fa)); + fixed_t pz = P_FloorzAtPos(px, py, actor->z, actor->height); + + dust = P_SpawnMobj(px, py, pz, MT_ARIDDUST); + P_SetMobjState(dust, (statenum_t)(dust->state + P_RandomRange(0, 2))); + P_Thrust(dust, angle, FixedDiv(12*FRACUNIT, max(FRACUNIT, fdist/2))); + dust->momx += actor->momx; + dust->momy += actor->momy; + angle += ANGLE_45; + } + } +} + +// Function: A_VultureHover +// +// Description: Vulture hovering and checking whether to attack. +// +// var1 = unused +// var2 = unused +// +void A_VultureHover(mobj_t *actor) +{ + fixed_t targetz; + fixed_t distdif; + fixed_t memz = actor->z; + INT8 i; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_VultureHover", actor)) + return; +#endif + + if (!actor->target) + { + P_SetMobjState(actor, actor->info->spawnstate); + return; + } + + actor->flags |= MF_NOGRAVITY; + + actor->momx -= actor->momx/24; + actor->momy -= actor->momy/24; + + P_VultureHoverParticle(actor); + + A_FaceTarget(actor); + targetz = actor->target->z + actor->target->height / 2; + for (i = -1; i <= 1; i++) + { + actor->z = targetz - i * 128 * FRACUNIT; + if (P_CheckSight(actor, actor->target)) + { + targetz -= i * 128 * FRACUNIT; + break; + } + } + actor->z = memz; + + distdif = (actor->z + actor->height/2) - targetz; + + if (abs(actor->momz*16) > abs(distdif)) + actor->momz -= actor->momz/16; + else if (distdif < 0) + actor->momz = min(actor->momz+FRACUNIT/8, actor->info->speed*FRACUNIT); + else + actor->momz = max(actor->momz-FRACUNIT/8, -actor->info->speed*FRACUNIT); + + if (abs(distdif) < 128*FRACUNIT && abs(actor->momz) < FRACUNIT && P_CheckSight(actor, actor->target)) + { + P_SetMobjState(actor, actor->info->missilestate); + actor->momx = 0; + actor->momy = 0; + actor->momz = 0; + actor->extravalue1 = 0; + } +} + +// Function: A_VultureBlast +// +// Description: Vulture spawning a dust cloud. +// +// var1 = unused +// var2 = unused +// +void A_VultureBlast(mobj_t *actor) +{ + mobj_t *dust; + UINT8 i; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_VultureBlast", actor)) + return; +#endif + + S_StartSound(actor, actor->info->attacksound); + + for (i = 0; i <= 7; i++) + { + angle_t fa = ((i*(angle_t)ANGLE_45) >> ANGLETOFINESHIFT) & FINEMASK; + angle_t faa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; + dust = P_SpawnMobj(actor->x + 48*FixedMul(FINECOSINE(fa), -FINESINE(faa)), actor->y + 48*FixedMul(FINECOSINE(fa), FINECOSINE(faa)), actor->z + actor->height/2 + 48*FINESINE(fa), MT_PARTICLE); + + P_SetScale(dust, 4*FRACUNIT); + dust->destscale = FRACUNIT; + dust->scalespeed = 4*FRACUNIT/TICRATE; + dust->fuse = TICRATE; + dust->momx = FixedMul(FINECOSINE(fa), -FINESINE(faa))*3; + dust->momy = FixedMul(FINECOSINE(fa), FINECOSINE(faa))*3; + dust->momz = FINESINE(fa)*6; + } +} + +// Function: A_VultureFly +// +// Description: Vulture charging towards target. +// +// var1 = unused +// var2 = unused +// +void A_VultureFly(mobj_t *actor) +{ + fixed_t speedmax = 18*FRACUNIT; + angle_t angledif = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) - actor->angle; + fixed_t dx = actor->target->x - actor->x; + fixed_t dy = actor->target->y - actor->y; + fixed_t dz = actor->target->z - actor->z; + fixed_t dxy = FixedHypot(dx, dy); + fixed_t dm; + mobj_t *dust; + fixed_t momm; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_VultureFly", actor)) + return; +#endif + + if (leveltime % 4 == 0) + S_StartSound(actor, actor->info->activesound); + + // Tweak the target height according to the position. + if (abs(angledif) < ANGLE_45) // Centered? + { + actor->reactiontime = actor->info->reactiontime; + if (dxy > 768*FRACUNIT) + dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + min(dxy/8, 128*FRACUNIT), dz); + } + else + { + actor->reactiontime--; + + if (abs(angledif) < ANGLE_90) + dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + min(dxy/2, 192*FRACUNIT), dz); + else + dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + 232*FRACUNIT, dz); + } + + dm = FixedHypot(dz, dxy); + + P_VultureHoverParticle(actor); + + dust = P_SpawnMobj(actor->x + P_RandomFixed() - FRACUNIT/2, actor->y + P_RandomFixed() - FRACUNIT/2, actor->z + actor->height/2 + P_RandomFixed() - FRACUNIT/2, MT_PARTICLE); + P_SetScale(dust, 2*FRACUNIT); + dust->destscale = FRACUNIT/3; + dust->scalespeed = FRACUNIT/40; + dust->fuse = TICRATE*2; + + actor->momx += FixedDiv(dx, dm)*2; + actor->momy += FixedDiv(dy, dm)*2; + actor->momz += FixedDiv(dz, dm)*2; + + momm = FixedHypot(actor->momz, FixedHypot(actor->momx, actor->momy)); + + if (momm > speedmax/2 && actor->reactiontime == 0) + { + P_SetMobjState(actor, actor->info->seestate); + return; + } + + //Hits a wall hard? + if (actor->extravalue1 - momm > 15*FRACUNIT) + { + actor->flags &= ~MF_NOGRAVITY; + P_SetMobjState(actor, actor->info->painstate); + S_StopSound(actor); + S_StartSound(actor, actor->info->painsound); + return; + } + actor->extravalue1 = momm; + + if (momm > speedmax) + { + actor->momx = FixedMul(FixedDiv(actor->momx, momm), speedmax); + actor->momy = FixedMul(FixedDiv(actor->momy, momm), speedmax); + actor->momz = FixedMul(FixedDiv(actor->momz, momm), speedmax); + } + + actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); +} + // Function: A_SkimChase // // Description: Thinker/Chase routine for Skims diff --git a/src/p_map.c b/src/p_map.c index ca4548d0b..db3dac86b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -853,6 +853,17 @@ static boolean PIT_CheckThing(mobj_t *thing) P_DamageMobj(thing, tmthing, tmthing, 1, 0); } + if (thing->type == MT_VULTURE && tmthing->type == MT_VULTURE) + { + fixed_t dx = thing->x - tmthing->x; + fixed_t dy = thing->y - tmthing->y; + fixed_t dz = thing->z - tmthing->z; + fixed_t dm = FixedHypot(dz, FixedHypot(dx, dy)); + thing->momx += FixedDiv(dx, dm); + thing->momy += FixedDiv(dy, dm); + thing->momz += FixedDiv(dz, dm); + } + if (tmthing->type == MT_FANG && thing->type == MT_FSGNB) { if (thing->z > tmthing->z + tmthing->height) From 85eece29d34acddac9d9fd5e3fe50ff3d3a157ce Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 10 Jun 2019 16:19:58 +0200 Subject: [PATCH 12/51] Fixed the bug --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 450cba37a..9dbb6e46e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2322,7 +2322,7 @@ static void P_VultureHoverParticle(mobj_t *actor) fixed_t pz = P_FloorzAtPos(px, py, actor->z, actor->height); dust = P_SpawnMobj(px, py, pz, MT_ARIDDUST); - P_SetMobjState(dust, (statenum_t)(dust->state + P_RandomRange(0, 2))); + P_SetMobjState(dust, (statenum_t)(dust->state - states + P_RandomRange(0, 2))); P_Thrust(dust, angle, FixedDiv(12*FRACUNIT, max(FRACUNIT, fdist/2))); dust->momx += actor->momx; dust->momy += actor->momy; From 0e80d2ec5d212cf534e1a4d8acffbd8c17884580 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 10 Jun 2019 17:42:37 +0200 Subject: [PATCH 13/51] Hardcoded the new Minus behavior --- src/dehacked.c | 22 +++++- src/hardware/hw_light.c | 1 + src/info.c | 66 +++++++++++++++--- src/info.h | 23 ++++++- src/p_enemy.c | 149 +++++++++++++++++++++++++++++----------- src/sounds.c | 6 +- 6 files changed, 210 insertions(+), 57 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index a76e7c9f0..c4b8ca3bc 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4450,8 +4450,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_GSNAPPER4", // Minus + "S_MINUS_INIT", "S_MINUS_STND", - "S_MINUS_DIGGING", + "S_MINUS_DIGGING1", + "S_MINUS_DIGGING2", + "S_MINUS_DIGGING3", + "S_MINUS_DIGGING4", + "S_MINUS_BURST0", + "S_MINUS_BURST1", + "S_MINUS_BURST2", + "S_MINUS_BURST3", + "S_MINUS_BURST4", + "S_MINUS_BURST5", "S_MINUS_POPUP", "S_MINUS_UPWARD1", "S_MINUS_UPWARD2", @@ -4470,6 +4480,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_MINUS_DOWNWARD7", "S_MINUS_DOWNWARD8", + // Minus dirt + "S_MINUSDIRT1", + "S_MINUSDIRT2", + "S_MINUSDIRT3", + "S_MINUSDIRT4", + "S_MINUSDIRT5", + "S_MINUSDIRT6", + "S_MINUSDIRT7", + // Spring Shell "S_SSHELL_STND", "S_SSHELL_RUN1", @@ -7157,6 +7176,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_EGGSHIELD", // Egg Guard's shield "MT_GSNAPPER", // Green Snapper "MT_MINUS", // Minus + "MT_MINUSDIRT", // Minus dirt "MT_SPRINGSHELL", // Spring Shell "MT_YELLOWSHELL", // Spring Shell (yellow) "MT_UNIDUS", // Unidus diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 4c4e369e6..874670266 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -173,6 +173,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_ESHI &lspr[NOLIGHT], // SPR_GSNP &lspr[NOLIGHT], // SPR_MNUS + &lspr[NOLIGHT], // SPR_MNUD &lspr[NOLIGHT], // SPR_SSHL &lspr[NOLIGHT], // SPR_UNID &lspr[NOLIGHT], // SPR_CANA diff --git a/src/info.c b/src/info.c index cc0ad09f7..d5b9271b3 100644 --- a/src/info.c +++ b/src/info.c @@ -61,6 +61,7 @@ char sprnames[NUMSPRITES + 1][5] = "ESHI", // Egg Guard's shield "GSNP", // Green Snapper "MNUS", // Minus + "MNUD", // Minus dirt "SSHL", // Spring Shell "UNID", // Unidus "CANA", // Canarivore @@ -1060,8 +1061,18 @@ state_t states[NUMSTATES] = {SPR_GSNP, 3, 2, {A_Chase}, 0, 0, S_GSNAPPER1}, // S_GSNAPPER4 // Minus - {SPR_NULL, 0, 1, {A_Look}, 0, 0, S_MINUS_STND}, // S_MINUS_STND - {SPR_MNUS, 16, 1, {A_MinusDigging}, 0, 0, S_MINUS_DIGGING}, // S_MINUS_DIGGING + {SPR_MNUD, 0, 1, {NULL}, 0, 0, S_MINUS_STND}, // S_MINUS_INIT (required for objectplace to work) + {SPR_NULL, 0, 10, {A_Look}, 0, 0, S_MINUS_STND}, // S_MINUS_STND + {SPR_NULL, 0, 1, {A_MinusDigging}, 1, 0, S_MINUS_DIGGING2}, // S_MINUS_DIGGING1 + {SPR_NULL, 0, 1, {A_MinusDigging}, 0, 0, S_MINUS_DIGGING3}, // S_MINUS_DIGGING2 + {SPR_NULL, 0, 1, {A_MinusDigging}, 0, 0, S_MINUS_DIGGING4}, // S_MINUS_DIGGING3 + {SPR_NULL, 0, 1, {A_MinusDigging}, 0, 0, S_MINUS_DIGGING1}, // S_MINUS_DIGGING4 + {SPR_NULL, 0, 25, {NULL}, 0, 0, S_MINUS_POPUP}, // S_MINUS_BURST0 + {SPR_MNUD, FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST2}, // S_MINUS_BURST1 + {SPR_MNUD, 1|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST3}, // S_MINUS_BURST2 + {SPR_MNUD, 2|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST4}, // S_MINUS_BURST3 + {SPR_MNUD, 3|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUS_BURST5}, // S_MINUS_BURST4 + {SPR_MNUD, 4|FF_ANIMATE, 5, {NULL}, 1, 2, S_MINUSDIRT2}, // S_MINUS_BURST5 {SPR_MNUS, 0, 1, {A_MinusPopup}, 0, 0, S_MINUS_UPWARD1}, // S_MINUS_POPUP {SPR_MNUS, 0, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD2}, // S_MINUS_UPWARD1 {SPR_MNUS, 1, 1, {A_MinusCheck}, 0, 0, S_MINUS_UPWARD3}, // S_MINUS_UPWARD2 @@ -1080,6 +1091,14 @@ state_t states[NUMSTATES] = {SPR_MNUS, 14, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD8}, // S_MINUS_DOWNWARD7 {SPR_MNUS, 15, 1, {A_MinusCheck}, 0, 0, S_MINUS_DOWNWARD1}, // S_MINUS_DOWNWARD8 + {SPR_MNUD, FF_ANIMATE, 6, {NULL}, 1, 5, S_MINUSDIRT2}, // S_MINUSDIRT1 + {SPR_MNUD, 5, 8, {NULL}, 3, 5, S_MINUSDIRT3}, // S_MINUSDIRT2 + {SPR_MNUD, 4, 8, {NULL}, 3, 5, S_MINUSDIRT4}, // S_MINUSDIRT3 + {SPR_MNUD, 3, 8, {NULL}, 3, 5, S_MINUSDIRT5}, // S_MINUSDIRT4 + {SPR_MNUD, 2, 8, {NULL}, 3, 5, S_MINUSDIRT6}, // S_MINUSDIRT5 + {SPR_MNUD, 1, 8, {NULL}, 3, 5, S_MINUSDIRT7}, // S_MINUSDIRT6 + {SPR_MNUD, 0, 8, {NULL}, 3, 5, S_NULL}, // S_MINUSDIRT7 + // Spring Shell {SPR_SSHL, 0, 4, {A_Look}, 0, 0, S_SSHELL_STND}, // S_SSHELL_STND {SPR_SSHL, 0, 4, {A_Chase}, 0, 0, S_SSHELL_RUN2}, // S_SSHELL_RUN1 @@ -4687,29 +4706,56 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_MINUS 121, // doomednum - S_MINUS_STND, // spawnstate + S_MINUS_INIT, // spawnstate 1, // spawnhealth - S_MINUS_DIGGING,// seestate + S_MINUS_DIGGING1,// seestate sfx_None, // seesound 32, // reactiontime - sfx_s3k82, // attacksound + sfx_s3kccs, // attacksound S_NULL, // painstate 200, // painchance sfx_None, // painsound - S_MINUS_DOWNWARD1,// meleestate + S_MINUS_BURST0, // meleestate S_MINUS_POPUP, // missilestate S_XPLD_FLICKY, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - 12, // speed + 17, // speed 24*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage - sfx_mindig, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags - S_MINUS_UPWARD1 // raisestate + sfx_s3kd3s, // activesound + MF_ENEMY|MF_NOCLIPTHING, // flags + S_MINUS_BURST1 // raisestate + }, + + { // MT_MINUSDIRT + -1, // doomednum + S_MINUSDIRT1, // 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 + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING, // flags + S_NULL // raisestate }, { // MT_SPRINGSHELL diff --git a/src/info.h b/src/info.h index 6e544d2d6..fd60902ff 100644 --- a/src/info.h +++ b/src/info.h @@ -301,6 +301,7 @@ typedef enum sprite SPR_ESHI, // Egg Guard's shield SPR_GSNP, // Green Snapper SPR_MNUS, // Minus + SPR_MNUD, // Minus dirt SPR_SSHL, // Spring Shell SPR_UNID, // Unidus SPR_CANA, // Canarivore @@ -1208,8 +1209,18 @@ typedef enum state S_GSNAPPER4, // Minus + S_MINUS_INIT, S_MINUS_STND, - S_MINUS_DIGGING, + S_MINUS_DIGGING1, + S_MINUS_DIGGING2, + S_MINUS_DIGGING3, + S_MINUS_DIGGING4, + S_MINUS_BURST0, + S_MINUS_BURST1, + S_MINUS_BURST2, + S_MINUS_BURST3, + S_MINUS_BURST4, + S_MINUS_BURST5, S_MINUS_POPUP, S_MINUS_UPWARD1, S_MINUS_UPWARD2, @@ -1228,6 +1239,15 @@ typedef enum state S_MINUS_DOWNWARD7, S_MINUS_DOWNWARD8, + // Minus dirt + S_MINUSDIRT1, + S_MINUSDIRT2, + S_MINUSDIRT3, + S_MINUSDIRT4, + S_MINUSDIRT5, + S_MINUSDIRT6, + S_MINUSDIRT7, + // Spring Shell S_SSHELL_STND, S_SSHELL_RUN1, @@ -3935,6 +3955,7 @@ typedef enum mobj_type MT_EGGSHIELD, // Egg Guard's shield MT_GSNAPPER, // Green Snapper MT_MINUS, // Minus + MT_MINUSDIRT, // Minus dirt MT_SPRINGSHELL, // Spring Shell MT_YELLOWSHELL, // Spring Shell (yellow) MT_UNIDUS, // Unidus diff --git a/src/p_enemy.c b/src/p_enemy.c index 9dbb6e46e..2d4b39ff0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5143,56 +5143,110 @@ void A_ShootBullet(mobj_t *actor) S_StartSound(actor, actor->info->attacksound); } +static mobj_t *minus; + +static boolean PIT_MinusCarry(mobj_t *thing) +{ + if (minus->type == thing->type) + return true; + + if (!(thing->flags & MF_SHOOTABLE) || !(thing->flags & MF_ENEMY)) + return true; + + if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius * 3) + return true; + + if (abs(thing->z - minus->z) > minus->height) + return true; + + minus->tracer = thing; + minus->tracer->flags &= ~MF_PUSHABLE; + + return true; +} + // Function: A_MinusDigging // // Description: Minus digging in the ground. // -// var1 = unused +// var1 = If 1, play digging sound. // var2 = unused // void A_MinusDigging(mobj_t *actor) { + INT32 locvar1 = var1; + INT32 rad = 32; + angle_t fa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t dis = actor->info->speed*4; + fixed_t x = FINECOSINE(fa)*dis + actor->x + FRACUNIT*P_RandomRange(-rad, rad); + fixed_t y = FINESINE(fa)*dis + actor->y + FRACUNIT*P_RandomRange(-rad, rad); + fixed_t mz = (actor->eflags & MFE_VERTICALFLIP) ? actor->ceilingz : actor->floorz; + #ifdef HAVE_BLUA if (LUA_CallAction("A_MinusDigging", actor)) return; #endif - actor->flags &= ~MF_SPECIAL; - actor->flags &= ~MF_SHOOTABLE; if (!actor->target) { - A_Look(actor); + P_SetMobjState(actor, actor->info->spawnstate); return; } - if (actor->reactiontime) + mobj_t *par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); + if (actor->eflags & MFE_VERTICALFLIP) + par->eflags |= MFE_VERTICALFLIP; + P_TryMove(par, x, y, false); + + // If close enough, prepare to attack + if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) { - actor->reactiontime--; + P_SetMobjState(actor, actor->info->meleestate); + P_TryMove(actor, actor->target->x, actor->target->y, false); + S_StartSound(actor, actor->info->attacksound); + + // Spawn growing dirt pile. + mobj_t *par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); + P_SetMobjState(par, actor->info->raisestate); + P_SetScale(par, actor->scale*2); + if (actor->eflags & MFE_VERTICALFLIP) + par->eflags |= MFE_VERTICALFLIP; return; } - // Dirt trail - P_SpawnGhostMobj(actor); - - actor->flags |= MF_NOCLIPTHING; - var1 = 3; - A_Chase(actor); - actor->flags &= ~MF_NOCLIPTHING; - // Play digging sound - if (!(leveltime & 15)) - S_StartSound(actor, actor->info->activesound); + if (locvar1 == 1) + A_PlayActiveSound(actor); - // If we're close enough to our target, pop out of the ground - if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) < actor->radius - && abs(actor->target->z - actor->z) < 2*actor->height) - P_SetMobjState(actor, actor->info->missilestate); + // Move + var1 = 3; + A_Chase(actor); - // Snap to ground - if (actor->eflags & MFE_VERTICALFLIP) - actor->z = actor->ceilingz - actor->height; + // Carry over shit, maybe + if (!actor->tracer) + { + fixed_t radius = 3*actor->radius; + fixed_t yh = (unsigned)(actor->y + radius - bmaporgy) >> MAPBLOCKSHIFT; + fixed_t yl = (unsigned)(actor->y - radius - bmaporgy) >> MAPBLOCKSHIFT; + fixed_t xh = (unsigned)(actor->x + radius - bmaporgx) >> MAPBLOCKSHIFT; + fixed_t xl = (unsigned)(actor->x - radius - bmaporgx) >> MAPBLOCKSHIFT; + fixed_t bx, by; + + BMBOUNDFIX(xl, xh, yl, yh); + + minus = actor; + + for (bx = xl; bx <= xh; bx++) + for (by = yl; by <= yh; by++) + P_BlockThingsIterator(bx, by, PIT_MinusCarry); + } else - actor->z = actor->floorz; + { + if (P_TryMove(actor->tracer, actor->x, actor->y, false)) + actor->tracer->z = mz; + else + actor->tracer = NULL; + } } // Function: A_MinusPopup @@ -5204,45 +5258,56 @@ void A_MinusDigging(mobj_t *actor) // void A_MinusPopup(mobj_t *actor) { + INT32 num = 6; + angle_t ani = FixedAngle(FRACUNIT*360/num); + INT32 i; + #ifdef HAVE_BLUA if (LUA_CallAction("A_MinusPopup", actor)) return; #endif - P_SetObjectMomZ(actor, 10*FRACUNIT, false); - actor->flags |= MF_SPECIAL; - actor->flags |= MF_SHOOTABLE; + if (actor->eflags & MFE_VERTICALFLIP) + actor->momz = -10*FRACUNIT; + else + actor->momz = 10*FRACUNIT; + + actor->flags |= MF_SPECIAL|MF_SHOOTABLE; + S_StartSound(actor, sfx_s3k82); + for (i = 1; i <= num; i++) + { + mobj_t *rock = P_SpawnMobj(actor->x, actor->y, actor->z + actor->height/4, MT_ROCKCRUMBLE1); + P_Thrust(rock, ani*i, FRACUNIT); + rock->momz = 3*FRACUNIT; + P_SetScale(rock, FRACUNIT/3); + } + P_RadiusAttack(actor, actor, 2*actor->radius, 0); + if (actor->tracer) + P_DamageMobj(actor->tracer, actor, actor, 1, 0); - // Sound for busting out of the ground. - S_StartSound(actor, actor->info->attacksound); } // Function: A_MinusCheck // // Description: If the minus hits the floor, dig back into the ground. // -// var1 = unused +// var1 = State to switch to (if 0, use seestate). // var2 = unused // void A_MinusCheck(mobj_t *actor) { + INT32 locvar1 = var1; + #ifdef HAVE_BLUA if (LUA_CallAction("A_MinusCheck", actor)) return; #endif - if ((!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz) - || ((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz)) - { - actor->flags &= ~MF_SPECIAL; - actor->flags &= ~MF_SHOOTABLE; - actor->reactiontime = TICRATE; - P_SetMobjState(actor, actor->info->seestate); - return; - } - // 'Falling' animation - if (P_MobjFlip(actor)*actor->momz < 0 && actor->state < &states[actor->info->meleestate]) - P_SetMobjState(actor, actor->info->meleestate); + if (((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz) || (!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz)) + { + P_SetMobjState(actor, locvar1 ? locvar1 : actor->info->seestate); + actor->flags = actor->info->flags; + } } // Function: A_ChickenCheck diff --git a/src/sounds.c b/src/sounds.c index 84b2c8a0c..5cfa59508 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -456,7 +456,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, {"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, // ditto {"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, - {"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominuous rumbling"}, // ditto + {"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto {"s3kccs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"}, {"s3kccl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"}, // ditto {"s3kcds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, @@ -471,8 +471,8 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kd1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto {"s3kd2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turning"}, {"s3kd2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Moving chain"}, // ditto - {"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto + {"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Digging"}, + {"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Digging"}, // ditto {"s3kd4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"}, {"s3kd4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"}, // ditto {"s3kd5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling lava"}, From 068e07974df4ad1276291a44c9c1ce95cf4d7c64 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 10 Jun 2019 20:32:50 +0200 Subject: [PATCH 14/51] Hardcoded the new Snapper behavior --- src/dehacked.c | 11 ++ src/hardware/hw_light.c | 2 + src/info.c | 84 +++++++++++-- src/info.h | 13 ++ src/p_enemy.c | 261 ++++++++++++++++++++++++++++++++++++++++ src/sounds.c | 2 +- 6 files changed, 361 insertions(+), 12 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c4b8ca3bc..8c88521fb 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2402,6 +2402,9 @@ static actionpointer_t actionpointers[] = {{A_TrainCameo}, "A_TRAINCAMEO"}, {{A_TrainCameo2}, "A_TRAINCAMEO2"}, {{A_CanarivoreGas}, "A_CANARIVOREGAS"}, + {{A_KillSegments}, "A_KILLSEGMENTS"}, + {{A_SnapperSpawn}, "A_SNAPPERSPAWN"}, + {{A_SnapperThinker}, "A_SNAPPERTHINKER"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -4443,11 +4446,17 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGGSHIELDBREAK", // Green Snapper + "S_SNAPPER_SPAWN", + "S_SNAPPER_SPAWN2", "S_GSNAPPER_STND", "S_GSNAPPER1", "S_GSNAPPER2", "S_GSNAPPER3", "S_GSNAPPER4", + "S_SNAPPER_XPLD", + "S_SNAPPER_LEG", + "S_SNAPPER_LEGRAISE", + "S_SNAPPER_HEAD", // Minus "S_MINUS_INIT", @@ -7175,6 +7184,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_EGGGUARD", // Egg Guard "MT_EGGSHIELD", // Egg Guard's shield "MT_GSNAPPER", // Green Snapper + "MT_SNAPPER_LEG", // Green Snapper leg + "MT_SNAPPER_HEAD", // Green Snapper head "MT_MINUS", // Minus "MT_MINUSDIRT", // Minus dirt "MT_SPRINGSHELL", // Spring Shell diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 874670266..8c302909f 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -172,6 +172,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_SPSH &lspr[NOLIGHT], // SPR_ESHI &lspr[NOLIGHT], // SPR_GSNP + &lspr[NOLIGHT], // SPR_GSNL + &lspr[NOLIGHT], // SPR_GSNH &lspr[NOLIGHT], // SPR_MNUS &lspr[NOLIGHT], // SPR_MNUD &lspr[NOLIGHT], // SPR_SSHL diff --git a/src/info.c b/src/info.c index d5b9271b3..692d485ea 100644 --- a/src/info.c +++ b/src/info.c @@ -60,6 +60,8 @@ char sprnames[NUMSPRITES + 1][5] = "SPSH", // Egg Guard "ESHI", // Egg Guard's shield "GSNP", // Green Snapper + "GSNL", // Green Snapper leg + "GSNH", // Green Snapper head "MNUS", // Minus "MNUD", // Minus dirt "SSHL", // Spring Shell @@ -1054,11 +1056,17 @@ state_t states[NUMSTATES] = {SPR_ESHI, 0, TICRATE/2, {NULL}, 0, 0, S_NULL}, // S_EGGSHIELDBREAK // Green Snapper - {SPR_GSNP, 0, 1, {A_Look}, 0, 0, S_GSNAPPER_STND}, // S_GSNAPPER_STND - {SPR_GSNP, 0, 2, {A_Chase}, 0, 0, S_GSNAPPER2}, // S_GSNAPPER1 - {SPR_GSNP, 1, 2, {A_Chase}, 0, 0, S_GSNAPPER3}, // S_GSNAPPER2 - {SPR_GSNP, 2, 2, {A_Chase}, 0, 0, S_GSNAPPER4}, // S_GSNAPPER3 - {SPR_GSNP, 3, 2, {A_Chase}, 0, 0, S_GSNAPPER1}, // S_GSNAPPER4 + {SPR_GSNP, 0, TICRATE, {NULL}, 0, 0, S_SNAPPER_SPAWN2}, // S_SNAPPER_SPAWN + {SPR_GSNP, 0, 2, {A_SnapperSpawn}, MT_SNAPPER_LEG, MT_SNAPPER_HEAD, S_GSNAPPER_STND}, // S_SNAPPER_SPAWN2 + {SPR_GSNP, 0, 1, {A_SnapperThinker}, 0, 0, S_GSNAPPER_STND}, // S_GSNAPPER_STND + {SPR_GSNP, 0, 2, {A_Chase}, 0, 0, S_GSNAPPER2}, // S_GSNAPPER1 + {SPR_GSNP, 1, 2, {A_Chase}, 0, 0, S_GSNAPPER3}, // S_GSNAPPER2 + {SPR_GSNP, 2, 2, {A_Chase}, 0, 0, S_GSNAPPER4}, // S_GSNAPPER3 + {SPR_GSNP, 3, 2, {A_Chase}, 0, 0, S_GSNAPPER1}, // S_GSNAPPER4 + {SPR_GSNP, 0, -1, {A_KillSegments}, 0, 0, S_XPLD_FLICKY}, // S_SNAPPER_XPLD + {SPR_GSNL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_LEG + {SPR_GSNL, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_LEGRAISE + {SPR_GSNH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_HEAD // Minus {SPR_MNUD, 0, 1, {NULL}, 0, 0, S_MINUS_STND}, // S_MINUS_INIT (required for objectplace to work) @@ -4679,28 +4687,82 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_GSNAPPER 120, // doomednum - S_GSNAPPER_STND,// spawnstate + S_SNAPPER_SPAWN,// spawnstate 1, // spawnhealth S_GSNAPPER1, // seestate sfx_None, // seesound - 32, // reactiontime + 10, // reactiontime sfx_None, // attacksound S_NULL, // painstate 200, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_XPLD_FLICKY, // deathstate + S_SNAPPER_XPLD, // deathstate S_NULL, // xdeathstate sfx_pop, // deathsound - 3, // speed + 4, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_s3k7e, // activesound + MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_SNAPPER_LEG + -1, // doomednum + S_SNAPPER_LEG, // 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 + 6*FRACUNIT, // radius + 12*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage sfx_None, // activesound - MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags + MF_SCENERY|MF_PAIN|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_SNAPPER_LEGRAISE // raisestate + }, + + { // MT_SNAPPER_HEAD + -1, // doomednum + S_SNAPPER_HEAD, // 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 + 6*FRACUNIT, // radius + 12*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_PAIN|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index fd60902ff..0616cf970 100644 --- a/src/info.h +++ b/src/info.h @@ -260,6 +260,9 @@ void A_DebrisRandom(); void A_TrainCameo(); void A_TrainCameo2(); void A_CanarivoreGas(); +void A_KillSegments(); +void A_SnapperSpawn(); +void A_SnapperThinker(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 @@ -300,6 +303,8 @@ typedef enum sprite SPR_SPSH, // Egg Guard SPR_ESHI, // Egg Guard's shield SPR_GSNP, // Green Snapper + SPR_GSNL, // Green Snapper leg + SPR_GSNH, // Green Snapper head SPR_MNUS, // Minus SPR_MNUD, // Minus dirt SPR_SSHL, // Spring Shell @@ -1202,11 +1207,17 @@ typedef enum state S_EGGSHIELDBREAK, // Green Snapper + S_SNAPPER_SPAWN, + S_SNAPPER_SPAWN2, S_GSNAPPER_STND, S_GSNAPPER1, S_GSNAPPER2, S_GSNAPPER3, S_GSNAPPER4, + S_SNAPPER_XPLD, + S_SNAPPER_LEG, + S_SNAPPER_LEGRAISE, + S_SNAPPER_HEAD, // Minus S_MINUS_INIT, @@ -3954,6 +3965,8 @@ typedef enum mobj_type MT_EGGGUARD, // Egg Guard MT_EGGSHIELD, // Egg Guard's shield MT_GSNAPPER, // Green Snapper + MT_SNAPPER_LEG, // Green Snapper leg + MT_SNAPPER_HEAD, // Green Snapper head MT_MINUS, // Minus MT_MINUSDIRT, // Minus dirt MT_SPRINGSHELL, // Spring Shell diff --git a/src/p_enemy.c b/src/p_enemy.c index 2d4b39ff0..0d545da66 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -289,6 +289,9 @@ void A_DebrisRandom(mobj_t *actor); void A_TrainCameo(mobj_t *actor); void A_TrainCameo2(mobj_t *actor); void A_CanarivoreGas(mobj_t *actor); +void A_KillSegments(mobj_t *actor); +void A_SnapperSpawn(mobj_t *actor); +void A_SnapperThinker(mobj_t *actor); //for p_enemy.c // @@ -13196,4 +13199,262 @@ void A_CanarivoreGas(mobj_t *actor) P_DustRing(locvar1, 4, actor->x, actor->y, actor->z + actor->height / 5, 18, 0, FRACUNIT/10, actor->scale); P_DustRing(locvar1, 6, actor->x, actor->y, actor->z + actor->height / 5, 28, FRACUNIT, FRACUNIT/10, actor->scale); +} + +// +// Function: A_KillSegments +// +// Description: Causes segments attached via tracer chain to be killed; forces into next state. +// +// var1 = Fuse (if 0, default to TICRATE/2). +// var2 = Unused +// +void A_KillSegments(mobj_t *actor) +{ + INT32 locvar1 = var1; + mobj_t *seg = actor->tracer; + INT32 fuse = locvar1 ? locvar1 : TICRATE/2; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_KillSegments", actor)) + return; +#endif + + while (seg) + { + mobj_t *kseg = seg; + seg = seg->tracer; + + kseg->flags = MF_NOBLOCKMAP|MF_BOUNCE; + kseg->flags2 = 0; + kseg->fuse = fuse; + P_Thrust(kseg, R_PointToAngle2(actor->x, actor->y, kseg->x, kseg->y), 3*actor->scale); + kseg->momz = 3*actor->scale; + } + + P_SetMobjState(actor, actor->state->nextstate); +} + +static void P_SnapperLegPlace(mobj_t *mo) +{ + mobj_t *seg = mo->tracer; + fixed_t x0 = mo->x; + fixed_t y0 = mo->y; + angle_t a = mo->angle; + angle_t fa = (a >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + fixed_t x, y; + INT32 o1, o2; + INT32 woffset = mo->extravalue1; + INT32 side = mo->extravalue2; + INT32 alt; + + // Move head first. + fixed_t rad = mo->radius; + INT32 necklen = (32*(mo->info->reactiontime - mo->reactiontime))/mo->info->reactiontime; // Not in FU + + P_TeleportMove(seg, mo->x + FixedMul(c, rad) + necklen*c, mo->y + FixedMul(s, rad) + necklen*s, mo->z + mo->height/3); + seg->angle = a; + + // Move as many legs as available. + seg = seg->tracer; + do + { + o1 = seg->extravalue1; + o2 = seg->extravalue2; + alt = seg->cusval; + + if (alt == 1) + o2 += woffset; + else + o2 -= woffset; + + if (alt != side) + { + x = c*o2 + s*o1; + y = s*o2 - c*o1; + P_TryMove(seg, x0 + x, y0 + y, true); + P_SetMobjState(seg, seg->info->raisestate); + } + else + P_SetMobjState(seg, seg->info->spawnstate); + + seg->angle = R_PointToAngle2(x0, y0, seg->x, seg->y); + + seg = seg->tracer; + } while (seg); +} + +// +// Function: A_SnapperSpawn +// +// Description: Sets up Green Snapper legs and head. +// +// var1 = Leg mobj type. +// var2 = Head mobj type. +// +void A_SnapperSpawn(mobj_t *actor) +{ + mobjtype_t legtype = (mobjtype_t)var1; + mobjtype_t headtype = (mobjtype_t)var2; + mobj_t *ptr = actor; + INT32 i; + mobj_t *seg; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_SnapperSpawn", actor)) + return; +#endif + + // It spawns 1 head. + seg = P_SpawnMobj(actor->x, actor->y, actor->z, headtype); + ptr->tracer = seg; + ptr = seg; + + // It spawns 4 legs which will be handled in the thinker function. + for (i = 1; i <= 4; i++) + { + seg = P_SpawnMobj(actor->x, actor->y, actor->z, legtype); + ptr->tracer = seg; + ptr = seg; + + // The legs' base offsets are stored as extravalues, as relative coordinates in xy space. + seg->extravalue1 = 28; + seg->extravalue2 = 28; + if (i % 2) + seg->extravalue1 = -seg->extravalue1; + + if ((i/2) % 2) + seg->extravalue2 = -seg->extravalue2; + + // Alternating motion stuff. + seg->cusval = ((i + 1)/2) % 2; + } + + actor->extravalue1 = 0; + actor->extravalue2 = 0; + P_SnapperLegPlace(actor); +} + +// +// Function: A_SnapperThinker +// +// Description: Thinker for Green Snapper. +// +// var1 = Unused +// var2 = Unused +// +void A_SnapperThinker(mobj_t *actor) +{ + fixed_t x0 = actor->x; + fixed_t y0 = actor->y; + fixed_t xs, ys; + fixed_t x1, y1; + fixed_t dist; + boolean chasing; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_SnapperThinker", actor)) + return; +#endif + + // We make a check just in case there's no spawnpoint. + if (actor->spawnpoint) + { + xs = actor->spawnpoint->x*FRACUNIT; + ys = actor->spawnpoint->y*FRACUNIT; + } + else + { + xs = x0; + ys = y0; + } + + // Look for nearby, valid players to chase angrily at. + if ((actor->target || P_LookForPlayers(actor, true, false, 1024*FRACUNIT)) + && P_AproxDistance(actor->target->x - xs, actor->target->y - ys) < 2048*FRACUNIT + && abs(actor->target->z - actor->z) < 80*FRACUNIT + && P_CheckSight(actor, actor->target)) + { + chasing = true; + x1 = actor->target->x; + y1 = actor->target->y; + } + else + { + chasing = false; + x1 = xs; + y1 = ys; + } + + dist = P_AproxDistance(x1 - x0, y1 - y0); + + // The snapper either chases what it considers to be a nearby player, or instead decides to go back to its spawnpoint. + if (chasing || dist > 32*FRACUNIT) + { + INT32 speed = actor->info->speed + actor->info->reactiontime - actor->reactiontime; + + angle_t maxang = FixedAngle(speed*FRACUNIT/2); + angle_t ang = actor->angle; + angle_t realang = R_PointToAngle2(x0, y0, x1, y1); + angle_t dif = realang - ang; + angle_t fa; + fixed_t c, s; + + if (dif < ANGLE_180 && dif > maxang) + actor->angle += maxang; + else if (dif >= ANGLE_180 && dif < InvAngle(maxang)) + actor->angle -= maxang; + else + actor->angle = realang; + + fa = (actor->angle >> ANGLETOFINESHIFT) & FINEMASK; + c = FINECOSINE(fa); + s = FINESINE(fa); + + P_TryMove(actor, actor->x + c*speed, actor->y + s*speed, false); + + // The snapper spawns dust if going fast! + if (actor->reactiontime < 4) + { + mobj_t *dust = P_SpawnMobj(x0, y0, actor->z, MT_SPINDUST); + P_Thrust(dust, ang + ANGLE_180 + FixedAngle(P_RandomRange(-20, 20)*FRACUNIT), speed*FRACUNIT); + } + + if (actor->extravalue2 == 0) + { + if (actor->extravalue1 > 16) + { + A_PlayActiveSound(actor); + actor->extravalue2 = 1; + + // If the snapper is chasing, accelerate; otherwise, decelerate. + if (chasing) + actor->reactiontime = max(0, actor->reactiontime - 1); + else + actor->reactiontime = min(actor->info->reactiontime, actor->reactiontime + 1); + } + else + actor->extravalue1 += speed; + } + else + { + if (actor->extravalue1 < -16) + { + A_PlayActiveSound(actor); + actor->extravalue2 = 0; + + // If the snapper is chasing, accelerate; otherwise, decelerate. + if (chasing) + actor->reactiontime = max(0, actor->reactiontime - 1); + else + actor->reactiontime = min(actor->info->reactiontime, actor->reactiontime + 1); + } + else + actor->extravalue1 -= speed; + } + } + + P_SnapperLegPlace(actor); } \ No newline at end of file diff --git a/src/sounds.c b/src/sounds.c index 5cfa59508..a707e4428 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -364,7 +364,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k7b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Soft bounce"}, {"s3k7c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnet"}, {"s3k7d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Eating dirt"}, + {"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dust"}, {"s3k7f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Freeze"}, {"s3k80", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ice spike burst"}, {"s3k81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"}, From 6a46fc76b81f7c41a7959b4ca43fcb72e69f0479 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 10 Jun 2019 20:40:12 +0200 Subject: [PATCH 15/51] Fixed some angle business in the BASH code --- src/p_enemy.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 0d545da66..149a6a3aa 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2460,8 +2460,11 @@ void A_VultureFly(mobj_t *actor) if (leveltime % 4 == 0) S_StartSound(actor, actor->info->activesound); + if (angledif > ANGLE_180) + angledif = InvAngle(angledif); + // Tweak the target height according to the position. - if (abs(angledif) < ANGLE_45) // Centered? + if (angledif < ANGLE_45) // Centered? { actor->reactiontime = actor->info->reactiontime; if (dxy > 768*FRACUNIT) @@ -2471,7 +2474,7 @@ void A_VultureFly(mobj_t *actor) { actor->reactiontime--; - if (abs(angledif) < ANGLE_90) + if (angledif < ANGLE_90) dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + min(dxy/2, 192*FRACUNIT), dz); else dz = max(P_FloorzAtPos(actor->target->x, actor->target->y, actor->target->z, 0) - actor->z + 232*FRACUNIT, dz); From fafabaae2bbb2268426051218cade6a5c34e1e81 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 12 Jun 2019 21:20:14 +0200 Subject: [PATCH 16/51] Hardcoded the saloon door --- src/d_player.h | 3 ++- src/dehacked.c | 8 ++++++ src/hardware/hw_light.c | 2 ++ src/info.c | 60 +++++++++++++++++++++++++++++++++++++++++ src/info.h | 9 +++++++ src/p_enemy.c | 52 +++++++++++++++++++++++++++++++++++ src/p_map.c | 15 +++++++++++ src/p_mobj.c | 28 +++++++++++++++++++ 8 files changed, 176 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index e68992e15..cdc899f5e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -232,7 +232,8 @@ typedef enum // Specific level gimmicks. CR_ZOOMTUBE, CR_ROPEHANG, - CR_MACESPIN + CR_MACESPIN, + CR_MINECART } carrytype_t; // pw_carry // Player powers. (don't edit this comment) diff --git a/src/dehacked.c b/src/dehacked.c index 8c88521fb..c7561cb7c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2405,6 +2405,7 @@ static actionpointer_t actionpointers[] = {{A_KillSegments}, "A_KILLSEGMENTS"}, {{A_SnapperSpawn}, "A_SNAPPERSPAWN"}, {{A_SnapperThinker}, "A_SNAPPERTHINKER"}, + {{A_SaloonDoorSpawn}, "A_SALOONDOORSPAWN"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -5785,6 +5786,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARIDDUST2", "S_ARIDDUST3", + // Saloon door + "S_SALOONDOOR", + "S_SALOONDOORTHINKER", + // Train cameo "S_TRAINCAMEOSPAWNER_1", "S_TRAINCAMEOSPAWNER_2", @@ -7498,6 +7503,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_DUSTDEVIL", "MT_DUSTLAYER", "MT_ARIDDUST", + "MT_SALOONDOOR", + "MT_SALOONDOORTHINKER", "MT_TRAINCAMEOSPAWNER", "MT_TRAINSEG", "MT_TRAINDUSTSPAWNER", @@ -8500,6 +8507,7 @@ struct { {"CR_ZOOMTUBE",CR_ZOOMTUBE}, {"CR_ROPEHANG",CR_ROPEHANG}, {"CR_MACESPIN",CR_MACESPIN}, + {"CR_MINECART",CR_MINECART}, // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 8c302909f..83fe8f16a 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -361,6 +361,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_REMT &lspr[NOLIGHT], // SPR_TAZD &lspr[NOLIGHT], // SPR_ADST + &lspr[NOLIGHT], // SPR_NON2 + &lspr[NOLIGHT], // SPR_SALD &lspr[NOLIGHT], // SPR_TRAE &lspr[NOLIGHT], // SPR_TRAI &lspr[NOLIGHT], // SPR_STEA diff --git a/src/info.c b/src/info.c index 692d485ea..2716baddb 100644 --- a/src/info.c +++ b/src/info.c @@ -256,6 +256,8 @@ char sprnames[NUMSPRITES + 1][5] = "REMT", // TNT proximity shell "TAZD", // Dust devil "ADST", // Arid dust + "NON2", // Saloon door thinker + "SALD", // Saloon door "TRAE", // Train cameo locomotive "TRAI", // Train cameo wagon "STEA", // Train steam @@ -2423,6 +2425,10 @@ state_t states[NUMSTATES] = {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 + // Saloon door + {SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR + {SPR_NON2, 0, -1, {A_SaloonDoorSpawn}, 0, 0, S_NULL}, // S_SALONDOORTHINKER + // Train cameo {SPR_NULL, 0, -1, {NULL}, 0, 0, S_TRAINCAMEOSPAWNER_2}, // S_TRAINCAMEOSPAWNER_1 {SPR_NULL, 0, 14, {A_TrainCameo}, 20, 18, S_TRAINCAMEOSPAWNER_3}, // S_TRAINCAMEOSPAWNER_2 @@ -11834,6 +11840,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SALOONDOOR + -1, // doomednum + S_SALOONDOOR, // 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 + 48*FRACUNIT, // radius + 160*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_s3k90, // activesound + MF_SOLID|MF_NOGRAVITY|MF_RUNSPAWNFUNC|MF_PAPERCOLLISION, // flags + S_NULL // raisestate + }, + + { // MT_SALOONDOORTHINKER + 1221, // doomednum + S_SALOONDOORTHINKER, // 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 + 96*FRACUNIT, // radius + 160*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, + { // MT_TRAINCAMEOSPAWNER 1222, // doomednum S_TRAINCAMEOSPAWNER_1, // spawnstate diff --git a/src/info.h b/src/info.h index 0616cf970..460f65ae0 100644 --- a/src/info.h +++ b/src/info.h @@ -263,6 +263,7 @@ void A_CanarivoreGas(); void A_KillSegments(); void A_SnapperSpawn(); void A_SnapperThinker(); +void A_SaloonDoorSpawn(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 @@ -499,6 +500,8 @@ typedef enum sprite SPR_REMT, // TNT proximity shell SPR_TAZD, // Dust devil SPR_ADST, // Arid dust + SPR_NON2, // Saloon door thinker + SPR_SALD, // Saloon door SPR_TRAE, // Train cameo locomotive SPR_TRAI, // Train cameo wagon SPR_STEA, // Train steam @@ -2546,6 +2549,10 @@ typedef enum state S_ARIDDUST2, S_ARIDDUST3, + // Saloon door + S_SALOONDOOR, + S_SALOONDOORTHINKER, + // Train cameo S_TRAINCAMEOSPAWNER_1, S_TRAINCAMEOSPAWNER_2, @@ -4279,6 +4286,8 @@ typedef enum mobj_type MT_DUSTDEVIL, MT_DUSTLAYER, MT_ARIDDUST, + MT_SALOONDOOR, + MT_SALOONDOORTHINKER, MT_TRAINCAMEOSPAWNER, MT_TRAINSEG, MT_TRAINDUSTSPAWNER, diff --git a/src/p_enemy.c b/src/p_enemy.c index 149a6a3aa..40e08b100 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -292,6 +292,7 @@ void A_CanarivoreGas(mobj_t *actor); void A_KillSegments(mobj_t *actor); void A_SnapperSpawn(mobj_t *actor); void A_SnapperThinker(mobj_t *actor); +void A_SaloonDoorSpawn(mobj_t *actor); //for p_enemy.c // @@ -13460,4 +13461,55 @@ void A_SnapperThinker(mobj_t *actor) } P_SnapperLegPlace(actor); +} + +// Function: A_SaloonDoorSpawn +// +// Description: Spawns a saloon door. +// +// var1 = unused +// var2 = unused +// +void A_SaloonDoorSpawn(mobj_t *actor) +{ + angle_t ang = actor->angle; + angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + INT32 d = 48; + fixed_t x = actor->x; + fixed_t y = actor->y; + fixed_t z = actor->z; + mobj_t *door; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_SaloonDoorSpawn", actor)) + return; +#endif + + //Front + door = P_SpawnMobj(x + c*d, y + s*d, z, MT_SALOONDOOR); + door->angle = ang + ANGLE_180; + + // Origin angle + door->extravalue1 = AngleFixed(door->angle); + + // Angular speed + door->extravalue2 = 0; + + // Origin door + door->tracer = actor; + + //Back + door = P_SpawnMobj(x - c*d, y - s*d, z, MT_SALOONDOOR); + door->angle = ang; + + // Origin angle + door->extravalue1 = AngleFixed(door->angle); + + // Angular speed + door->extravalue2 = 0; + + // Origin door + door->tracer = actor; } \ No newline at end of file diff --git a/src/p_map.c b/src/p_map.c index db3dac86b..bb98f8fdb 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -818,6 +818,21 @@ static boolean PIT_CheckThing(mobj_t *thing) } #endif + if (thing->type == MT_SALOONDOOR && tmthing->player) + { + if ((tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->player->mo->tracer && !P_MobjWasRemoved(tmthing->player->mo->tracer))) + { + fixed_t dx = tmthing->momx; + fixed_t dy = tmthing->momy; + fixed_t dm = min(FixedHypot(dx, dy), 16*FRACUNIT); + angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle; + fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK); + S_StartSound(tmthing, thing->info->activesound); + thing->extravalue2 += FixedMul(s, dm); + return true; + } + } + if (thing->type == MT_TNTBARREL && tmthing->player) { if (tmthing->momz < 0) diff --git a/src/p_mobj.c b/src/p_mobj.c index e3276fde4..214de7a11 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8467,6 +8467,34 @@ void P_MobjThinker(mobj_t *mobj) mobj->flags2 |= MF2_AMBUSH; break; } + case MT_SALOONDOOR: + { + fixed_t x = mobj->tracer->x; + fixed_t y = mobj->tracer->y; + fixed_t z = mobj->tracer->z; + angle_t oang = FixedAngle(mobj->extravalue1); + angle_t fa = (oang >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c0 = -96*FINECOSINE(fa); + fixed_t s0 = -96*FINESINE(fa); + angle_t fma; + fixed_t c, s; + + // Adjust angular speed + fixed_t da = AngleFixed(mobj->angle - oang); + if (da > 180*FRACUNIT) + da -= 360*FRACUNIT; + mobj->extravalue2 = 8*(mobj->extravalue2 - da/32)/9; + + // Update angle + mobj->angle += FixedAngle(mobj->extravalue2); + + // Update position + fma = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK; + c = 48*FINECOSINE(fma); + s = 48*FINESINE(fma); + P_TeleportMove(mobj, x + c0 + c, y + s0 + s, z); + break; + } case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) { From fae4dc3f21295f4609df3d6021b6d80e4c12acb8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 12 Jun 2019 21:28:09 +0200 Subject: [PATCH 17/51] Forgot to hardcode the mobj.valid checks --- src/p_enemy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 149a6a3aa..d943f9e78 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2353,7 +2353,7 @@ void A_VultureHover(mobj_t *actor) return; #endif - if (!actor->target) + if (!actor->target || P_MobjWasRemoved(actor->target)) { P_SetMobjState(actor, actor->info->spawnstate); return; @@ -12897,7 +12897,7 @@ void A_DustDevilThink(mobj_t *actor) #endif //Chained thinker for the spiralling dust column. - while (layer) { + while (layer && !P_MobjWasRemoved(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; From ba9c7d931041193969dd47de6359594753154175 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 13 Jun 2019 21:45:30 +0200 Subject: [PATCH 18/51] More incomplete minecart hardcoding --- src/dehacked.c | 20 ++++ src/hardware/hw_light.c | 2 + src/info.c | 203 ++++++++++++++++++++++++++++++++++++++++ src/info.h | 22 +++++ src/p_enemy.c | 38 ++++++++ src/p_inter.c | 54 +++++++++++ src/p_map.c | 18 +++- src/p_mobj.c | 14 +++ src/p_user.c | 2 +- src/sounds.c | 4 +- 10 files changed, 373 insertions(+), 4 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c7561cb7c..c546f4431 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2406,6 +2406,7 @@ static actionpointer_t actionpointers[] = {{A_SnapperSpawn}, "A_SNAPPERSPAWN"}, {{A_SnapperThinker}, "A_SNAPPERTHINKER"}, {{A_SaloonDoorSpawn}, "A_SALOONDOORSPAWN"}, + {{A_MinecartSparkThink}, "A_MINECARTSPARKTHINK"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -5786,6 +5787,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARIDDUST2", "S_ARIDDUST3", + // Minecart + "S_MINECART_IDLE", + "S_MINECART_DTH1", + "S_MINECARTEND", + "S_MINECARTSEG_FRONT", + "S_MINECARTSEG_BACK", + "S_MINECARTSEG_LEFT", + "S_MINECARTSEG_RIGHT", + "S_MINECARTSIDEMARK1", + "S_MINECARTSIDEMARK2", + "S_MINECARTSPARK", + // Saloon door "S_SALOONDOOR", "S_SALOONDOORTHINKER", @@ -7503,12 +7516,19 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_DUSTDEVIL", "MT_DUSTLAYER", "MT_ARIDDUST", + "MT_MINECART", + "MT_MINECARTSPAWNER", + "MT_MINECARTEND", + "MT_MINECARTENDSOLID", + "MT_MINECARTSIDEMARK", + "MT_MINECARTSPARK", "MT_SALOONDOOR", "MT_SALOONDOORTHINKER", "MT_TRAINCAMEOSPAWNER", "MT_TRAINSEG", "MT_TRAINDUSTSPAWNER", "MT_TRAINSTEAMSPAWNER", + "MT_MINECARTSWITCHPOINT", // Red Volcano Scenery "MT_FLAMEJET", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 83fe8f16a..8baa547af 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -361,6 +361,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_REMT &lspr[NOLIGHT], // SPR_TAZD &lspr[NOLIGHT], // SPR_ADST + &lspr[NOLIGHT], // SPR_MCRT + &lspr[NOLIGHT], // SPR_MCSP &lspr[NOLIGHT], // SPR_NON2 &lspr[NOLIGHT], // SPR_SALD &lspr[NOLIGHT], // SPR_TRAE diff --git a/src/info.c b/src/info.c index 2716baddb..eb170a1fe 100644 --- a/src/info.c +++ b/src/info.c @@ -256,6 +256,8 @@ char sprnames[NUMSPRITES + 1][5] = "REMT", // TNT proximity shell "TAZD", // Dust devil "ADST", // Arid dust + "MCRT", // Minecart + "MCSP", // Minecart spark "NON2", // Saloon door thinker "SALD", // Saloon door "TRAE", // Train cameo locomotive @@ -2425,6 +2427,18 @@ state_t states[NUMSTATES] = {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 + // Minecart + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_MINECART_IDLE}, // S_MINECART_IDLE + {SPR_NULL, 0, 45, {NULL}, 0, 0, S_NULL}, // S_MINECART_DTH1 + {SPR_MCRT, 8|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTEND + {SPR_MCRT, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_FRONT + {SPR_MCRT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_BACK + {SPR_MCRT, 2|FF_PAPERSPRITE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_LEFT + {SPR_MCRT, 5|FF_PAPERSPRITE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_RIGHT + {SPR_LCKN, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK1 + {SPR_LCKN, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK2 + {SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK + // Saloon door {SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR {SPR_NON2, 0, -1, {A_SaloonDoorSpawn}, 0, 0, S_NULL}, // S_SALONDOORTHINKER @@ -11840,6 +11854,168 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_MINECART + -1, // doomednum + S_MINECART_IDLE,// spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 24*FRACUNIT, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_statu2, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_MINECART_DTH1,// deathstate + S_NULL, // xdeathstate + sfx_s3k59, // deathsound + 20*FRACUNIT, // speed + 22*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_s3k76, // activesound + MF_PUSHABLE, // flags + MT_MINECARTSIDEMARK // raisestate + }, + + { // MT_MINECARTSPAWNER + 1219, // 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 + 22*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_MINECARTEND + 1220, // doomednum + S_MINECARTEND, // 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 + 160*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_MINECARTENDSOLID + -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 + 32*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID|MF_PAPERCOLLISION, // flags + S_NULL // raisestate + }, + + { // MT_MINECARTSIDEMARK + -1, // doomednum + S_MINECARTSIDEMARK1, // spawnstate + 1, // spawnhealth + S_MINECARTSIDEMARK2, // 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 + 22*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_MINECARTSPARK + -1, // doomednum + S_MINECARTSPARK,// 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 + 2*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_BOUNCE|MF_NOCLIPTHING|MF_GRENADEBOUNCE, // flags + S_NULL // raisestate + }, + { // MT_SALOONDOOR -1, // doomednum S_SALOONDOOR, // spawnstate @@ -12002,6 +12178,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_MINECARTSWITCHPOINT + 1229, // 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 + FRACUNIT, // radius + 160*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_FLAMEJET 1300, // doomednum S_FLAMEJETSTND, // spawnstate diff --git a/src/info.h b/src/info.h index 460f65ae0..717f659c9 100644 --- a/src/info.h +++ b/src/info.h @@ -264,6 +264,7 @@ void A_KillSegments(); void A_SnapperSpawn(); void A_SnapperThinker(); void A_SaloonDoorSpawn(); +void A_MinecartSparkThink(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 @@ -500,6 +501,8 @@ typedef enum sprite SPR_REMT, // TNT proximity shell SPR_TAZD, // Dust devil SPR_ADST, // Arid dust + SPR_MCRT, // Minecart + SPR_MCSP, // Minecart spark SPR_NON2, // Saloon door thinker SPR_SALD, // Saloon door SPR_TRAE, // Train cameo locomotive @@ -2549,6 +2552,18 @@ typedef enum state S_ARIDDUST2, S_ARIDDUST3, + // Minecart + S_MINECART_IDLE, + S_MINECART_DTH1, + S_MINECARTEND, + S_MINECARTSEG_FRONT, + S_MINECARTSEG_BACK, + S_MINECARTSEG_LEFT, + S_MINECARTSEG_RIGHT, + S_MINECARTSIDEMARK1, + S_MINECARTSIDEMARK2, + S_MINECARTSPARK, + // Saloon door S_SALOONDOOR, S_SALOONDOORTHINKER, @@ -4286,12 +4301,19 @@ typedef enum mobj_type MT_DUSTDEVIL, MT_DUSTLAYER, MT_ARIDDUST, + MT_MINECART, + MT_MINECARTSPAWNER, + MT_MINECARTEND, + MT_MINECARTENDSOLID, + MT_MINECARTSIDEMARK, + MT_MINECARTSPARK, MT_SALOONDOOR, MT_SALOONDOORTHINKER, MT_TRAINCAMEOSPAWNER, MT_TRAINSEG, MT_TRAINDUSTSPAWNER, MT_TRAINSTEAMSPAWNER, + MT_MINECARTSWITCHPOINT, // Red Volcano Scenery MT_FLAMEJET, diff --git a/src/p_enemy.c b/src/p_enemy.c index 61c9f7d7d..3c91ef393 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -293,6 +293,7 @@ void A_KillSegments(mobj_t *actor); void A_SnapperSpawn(mobj_t *actor); void A_SnapperThinker(mobj_t *actor); void A_SaloonDoorSpawn(mobj_t *actor); +void A_MinecartSparkThink(mobj_t *actor); //for p_enemy.c // @@ -13512,4 +13513,41 @@ void A_SaloonDoorSpawn(mobj_t *actor) // Origin door door->tracer = actor; +} + +// Function: A_MinecartSparkThink +// +// Description: Thinker for the minecart spark. +// +// var1 = unused +// var2 = unused +// +void A_MinecartSparkThink(mobj_t *actor) +{ + fixed_t dx = actor->momx; + fixed_t dy = actor->momy; + fixed_t dz, dm; + UINT8 i; + +#ifdef HAVE_BLUA + if (LUA_CallAction("A_MinecartSparkThink", actor)) + return; +#endif + + if (actor->momz == 0 && P_IsObjectOnGround(actor)) + actor->momz = P_RandomRange(2, 4)*FRACUNIT; + + dz = actor->momz; + dm = FixedHypot(FixedHypot(dx, dy), dz); + dx = FixedDiv(dx, dm); + dy = FixedDiv(dy, dm); + dz = FixedDiv(dz, dm); + + for (i = 1; i <= 8; i++) + { + mobj_t *trail = P_SpawnMobj(actor->x - dx*i, actor->y - dy*i, actor->z - dz*i, MT_PARTICLE); + trail->tics = 2; + trail->sprite = actor->sprite; + P_SetScale(trail, trail->scale/4); + } } \ No newline at end of file diff --git a/src/p_inter.c b/src/p_inter.c index aed63b208..b474c1a66 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1709,6 +1709,53 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->momz = toucher->momz; return; + case MT_MINECARTSPAWNER: + if (!special->fuse || player->powers[pw_carry] != CR_MINECART) + { + mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); + P_SetTarget(&mcart->target, toucher); + mcart->angle = toucher->angle = player->drawangle = special->angle; + mcart->friction = FRACUNIT; + + P_ResetPlayer(player); + player->powers[pw_carry] = CR_MINECART; + toucher->player->pflags &= ~PF_APPLYAUTOBRAKE; + P_SetTarget(&toucher->tracer, mcart); + toucher->momx = toucher->momy = toucher->momz = 0; + + special->fuse = 3*TICRATE; + special->flags2 |= MF2_DONTDRAW; + } + return; + + case MT_MINECARTEND: + if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health) + { + fixed_t maxz = max(toucher->z, special->z + 35*special->scale); + + toucher->momx = toucher->tracer->momx/2; + toucher->momy = toucher->tracer->momy/2; + toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2; + P_ResetPlayer(player); + player->pflags &= ~PF_APPLYAUTOBRAKE; + P_SetMobjState(toucher, S_PLAY_FALL); + P_SetTarget(&toucher->tracer->target, NULL); + P_KillMobj(toucher->tracer, toucher, special, 0); + P_SetTarget(&toucher->tracer, NULL); + player->powers[pw_carry] = CR_NONE; + P_TeleportMove(toucher, special->x, special->y, maxz); + } + return; + + case MT_MINECARTSWITCHPOINT: + if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health) + { + boolean destambush = special->flags & MF2_AMBUSH; + if ((toucher->tracer->angle - special->angle + ANGLE_90) >= ANGLE_180) + destambush ^= MF2_AMBUSH; + toucher->tracer->flags2 = (toucher->tracer->flags2 & ~MF2_AMBUSH) | destambush; + } + return; default: // SOC or script pickup if (player->bot) return; @@ -2556,6 +2603,13 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->fuse = TICRATE*2; break; + case MT_MINECART: + A_KillSegments(target); // found in green snapper's code - the minecart segments need hardcode-side support to flash while they have a nonzero fuse + A_Scream(target); + P_SetMobjState(target, S_TNTBARREL_EXPL3); + target->momx = target->momy = target->momz = 0; + break; + case MT_PLAYER: { target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player) diff --git a/src/p_map.c b/src/p_map.c index bb98f8fdb..5015e6a79 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -818,6 +818,22 @@ static boolean PIT_CheckThing(mobj_t *thing) } #endif + if (tmthing->type == MT_MINECART) + { + //height check + if (tmthing->z > thing->z + thing->height || thing->z > tmthing->z + tmthing->height || !(thing->health)) + return true; + + if (thing->type == MT_TNTBARREL) + P_KillMobj(thing, tmthing, tmthing->target, 0); + else if ((thing->flags & MF_MONITOR) || (thing->flags & MF_ENEMY)) + { + P_KillMobj(thing, tmthing, tmthing->target, 0); + if (tmthing->momz*P_MobjFlip(tmthing) < 0) + tmthing->momz = abs(tmthing->momz)*P_MobjFlip(tmthing); + } + } + if (thing->type == MT_SALOONDOOR && tmthing->player) { if ((tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->player->mo->tracer && !P_MobjWasRemoved(tmthing->player->mo->tracer))) @@ -1456,7 +1472,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_FAN || thing->type == MT_STEAM) P_DoFanAndGasJet(thing, tmthing); - else if (thing->flags & MF_SPRING) + else if (thing->flags & MF_SPRING && tmthing->player->powers[pw_carry] != CR_MINECART) { if ( thing->z <= tmthing->z + tmthing->height && tmthing->z <= thing->z + thing->height) diff --git a/src/p_mobj.c b/src/p_mobj.c index 214de7a11..6beec3684 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8495,6 +8495,16 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(mobj, x + c0 + c, y + s0 + s, z); break; } + case MT_MINECARTSPAWNER: + if (!mobj->fuse || mobj->fuse > TICRATE) + break; + if (mobj->fuse == 2) + { + mobj->fuse = 0; + break; + } + mobj->flags2 ^= MF2_DONTDRAW; + break; case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) { @@ -9245,6 +9255,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_TNTBARREL: mobj->momx = 1; //stack hack break; + case MT_MINECARTEND: + mobj->tracer = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_MINECARTENDSOLID); + mobj->tracer->angle = mobj->angle + ANGLE_90; + break; default: break; } diff --git a/src/p_user.c b/src/p_user.c index ca14c64d4..e5d3f4835 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -963,7 +963,7 @@ void P_ResetPlayer(player_t *player) { player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING); - if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP)) + if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP || player->powers[pw_carry] == CR_MINECART)) player->powers[pw_carry] = CR_NONE; player->secondjump = 0; diff --git a/src/sounds.c b/src/sounds.c index a707e4428..56de4a9c5 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -319,7 +319,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Big explosion"}, {"s3k4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"}, {"s3k50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Siren"}, - {"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling hazard"}, + {"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling"}, {"s3k52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"}, {"s3k53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"}, {"s3k54", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Firing"}, // MetalSonic shot fire @@ -388,7 +388,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gas release"}, {"s3k94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"}, {"s3k95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lava burst"}, - {"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling object"}, + {"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Landing"}, {"s3k97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind"}, {"s3k98", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling spike"}, {"s3k99", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"}, From 43f28b8f565a5c19a2d9bd6350c2a3089f706684 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 13 Jun 2019 21:51:31 +0200 Subject: [PATCH 19/51] Set tracers via P_SetTarget and not directly --- src/p_enemy.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index d943f9e78..301579812 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5165,7 +5165,7 @@ static boolean PIT_MinusCarry(mobj_t *thing) if (abs(thing->z - minus->z) > minus->height) return true; - minus->tracer = thing; + P_SetTarget(&minus->tracer, thing); minus->tracer->flags &= ~MF_PUSHABLE; return true; @@ -5251,7 +5251,7 @@ void A_MinusDigging(mobj_t *actor) if (P_TryMove(actor->tracer, actor->x, actor->y, false)) actor->tracer->z = mz; else - actor->tracer = NULL; + P_SetTarget(&actor->tracer, NULL); } } @@ -12934,8 +12934,8 @@ void A_DustDevilThink(mobj_t *actor) layer->extravalue1 = TICRATE * 3; //Chain them - layer->tracer = actor->tracer; - actor->tracer = layer; + P_SetTarget(&layer->tracer, actor->tracer); + P_SetTarget(&actor->tracer, layer); } } @@ -13312,14 +13312,14 @@ void A_SnapperSpawn(mobj_t *actor) // It spawns 1 head. seg = P_SpawnMobj(actor->x, actor->y, actor->z, headtype); - ptr->tracer = seg; + P_SetTarget(&ptr->tracer, seg); ptr = seg; // It spawns 4 legs which will be handled in the thinker function. for (i = 1; i <= 4; i++) { seg = P_SpawnMobj(actor->x, actor->y, actor->z, legtype); - ptr->tracer = seg; + P_SetTarget(&ptr->tracer, seg); ptr = seg; // The legs' base offsets are stored as extravalues, as relative coordinates in xy space. From 018fb9b461ed7581d8bab21243a2cf45c6c75248 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 14 Jun 2019 21:19:52 +0200 Subject: [PATCH 20/51] "Finished" minecart hardcoding (still untested and buggy) --- src/info.c | 20 +-- src/p_local.h | 1 + src/p_mobj.c | 70 +++++++++ src/p_user.c | 427 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 507 insertions(+), 11 deletions(-) diff --git a/src/info.c b/src/info.c index eb170a1fe..e58a1f3a7 100644 --- a/src/info.c +++ b/src/info.c @@ -2428,16 +2428,16 @@ state_t states[NUMSTATES] = {SPR_ADST, 6|FF_ANIMATE, 24, {NULL}, 3, 8, S_NULL}, // S_ARIDDUST3 // Minecart - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_MINECART_IDLE}, // S_MINECART_IDLE - {SPR_NULL, 0, 45, {NULL}, 0, 0, S_NULL}, // S_MINECART_DTH1 - {SPR_MCRT, 8|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTEND - {SPR_MCRT, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_FRONT - {SPR_MCRT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_BACK - {SPR_MCRT, 2|FF_PAPERSPRITE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_LEFT - {SPR_MCRT, 5|FF_PAPERSPRITE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_RIGHT - {SPR_LCKN, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK1 - {SPR_LCKN, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK2 - {SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_MINECART_IDLE}, // S_MINECART_IDLE + {SPR_NULL, 0, 45, {NULL}, 0, 0, S_NULL}, // S_MINECART_DTH1 + {SPR_MCRT, 8|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTEND + {SPR_MCRT, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_FRONT + {SPR_MCRT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_BACK + {SPR_MCRT, 2|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_LEFT + {SPR_MCRT, 5|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_RIGHT + {SPR_LCKN, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK1 + {SPR_LCKN, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK2 + {SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK // Saloon door {SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR diff --git a/src/p_local.h b/src/p_local.h index b686b9f09..2149a95bf 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -229,6 +229,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); void P_RunShields(void); void P_RunOverlays(void); +void P_HandleMinecartSegments(mobj_t *mobj); void P_MobjThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index 6beec3684..30f7fc7d4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6728,6 +6728,67 @@ static void P_KoopaThinker(mobj_t *koopa) } } +// Spawns and chains the minecart sides. +static void P_SpawnMinecartSegments(mobj_t *mobj, boolean mode) +{ + fixed_t x = mobj->x; + fixed_t y = mobj->y; + fixed_t z = mobj->z; + mobj_t *prevseg = mobj; + mobj_t *seg; + UINT8 i; + + for (i = 0; i < 4; i++) + { + seg = P_SpawnMobj(x, y, z, MT_PARTICLE); + P_SetMobjState(seg, (statenum_t)(S_MINECARTSEG_FRONT + i)); + if (i >= 2) + seg->extravalue1 = (i == 2) ? -18 : 18; + else + { + seg->extravalue2 = (i == 0) ? 24 : -24; + seg->cusval = -90; + } + if (mode) + seg->frame &= ~FF_ANIMATE; + P_SetTarget(&prevseg->tracer, seg); + prevseg = seg; + } +} + +// Updates the chained segments. +static void P_UpdateMinecartSegments(mobj_t *mobj) +{ + mobj_t *seg = mobj->tracer; + fixed_t x = mobj->x; + fixed_t y = mobj->y; + fixed_t z = mobj->z; + angle_t ang = mobj->angle; + angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + INT32 dx, dy; + INT32 sang; + + while (seg) + { + dx = seg->extravalue1; + dy = seg->extravalue2; + sang = seg->cusval; + P_TeleportMove(seg, x + s*dx + c*dy, y - c*dx + s*dy, z); + seg->angle = ang + FixedAngle(FRACUNIT*sang); + seg->flags2 = (seg->flags2 & ~MF2_DONTDRAW) | (mobj->flags2 & MF2_DONTDRAW); + seg = seg->tracer; + } +} + +void P_HandleMinecartSegments(mobj_t *mobj) +{ + if (!mobj->tracer) + P_SpawnMinecartSegments(mobj, (mobj->type == MT_MINECART)); + P_UpdateMinecartSegments(mobj); +} + // // P_MobjThinker // @@ -8496,6 +8557,7 @@ void P_MobjThinker(mobj_t *mobj) break; } case MT_MINECARTSPAWNER: + P_HandleMinecartSegments(mobj); if (!mobj->fuse || mobj->fuse > TICRATE) break; if (mobj->fuse == 2) @@ -8505,6 +8567,14 @@ void P_MobjThinker(mobj_t *mobj) } mobj->flags2 ^= MF2_DONTDRAW; break; + case MT_MINECART: + // If player is ded, remove this minecart + if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->health) + { + P_KillMobj(mobj, NULL, NULL, 0); + return; + } + break; case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) { diff --git a/src/p_user.c b/src/p_user.c index e5d3f4835..29988c88b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9753,6 +9753,421 @@ void P_DoPityCheck(player_t *player) } } +static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z) +{ + sector_t *sec = R_PointInSubsector(x, y)->sector; + + if ((sec->ceilingheight - sec->floorheight) < 64*FRACUNIT) + return NULL; + + if (sec->ffloors) + { + ffloor_t *rover; + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS)) + continue; + + fixed_t fofz = rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; + if (abs(z - fofz) <= 40*FRACUNIT) + { + sec = §ors[rover->secnum]; + break; + } + } + + } + return sec; +} + +static size_t P_GetMinecartSpecialLine(sector_t *sec) +{ + size_t line = -1; + + if (!sec) + return -1; + + if (sec->tag != 0) + line = P_FindSpecialLineFromTag(16, sec->tag, -1); + + // Also try for lines facing the sector itself, with tag 0. + if (line == -1) + { + UINT32 i; + for (i = 0; i < sec->linecount; i++) + { + line_t *li = sec->lines[i]; + if (li->tag == 0 && li->special == 16 && li->frontsector == sec) + line = i; + } + } + + return line; +} + +// Get an axis of a certain ID number +static mobj_t *P_GetAxis(UINT16 num) +{ + thinker_t *th; + mobj_t *mobj; + + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mobj = (mobj_t *)th; + + // NiGHTS axes spawn before anything else. If this mobj doesn't have MF2_AXIS, it means we reached the axes' end. + if (!(mobj->flags2 & MF2_AXIS)) + break; + + // Skip if this axis isn't the one we want. + if (!mobj->spawnpoint || mobj->spawnpoint->options != num) + continue; + + return mobj; + } + CONS_Debug(DBG_GAMELOGIC, "P_GetAxis: Track segment %d is missing!\n", num); + return NULL; +} + +// Auxiliary function. For a given position and axis, it calculates the nearest "valid" snap-on position. +static void P_GetAxisPosition(fixed_t x, fixed_t y, mobj_t *amo, fixed_t *newx, fixed_t *newy, angle_t *targetangle, angle_t *grind) +{ + fixed_t ax = amo->x; + fixed_t ay = amo->y; + angle_t ang; + angle_t gr = 0; + + if (amo->type == MT_AXISTRANSFERLINE) + { + ang = amo->angle; + // Extra security for cardinal directions. + if (ang == ANGLE_90 || ang == ANGLE_270) // Vertical lines + x = ax; + else if (ang == 0 || ang == ANGLE_180) // Horizontal lines + y = ay; + else // Diagonal lines + { + fixed_t distance = R_PointToDist2(ax, ay, x, y); + angle_t fad = ((R_PointToAngle2(ax, ay, x, y) - ang) >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t cosine = FINECOSINE(fad); + angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK; + distance = FixedMul(distance, cosine); + x = ax + FixedMul(distance, FINECOSINE(fa)); + y = ay + FixedMul(distance, FINESINE(fa)); + } + } + else // Keep minecart to circle + { + fixed_t rad; + fixed_t distfactor; + + gr = R_PointToAngle2(ax, ay, x, y); + ang = gr + ANGLE_90; + if (amo->spawnpoint->angle < 16384) // Counterclockwise + rad = amo->spawnpoint->angle*FRACUNIT; + else // Clockwise + rad = (amo->spawnpoint->angle - 16384)*FRACUNIT; + + distfactor = FixedDiv(rad, R_PointToDist2(ax, ay, x, y)); + x = ax + FixedMul(x - ax, distfactor); + y = ay + FixedMul(y - ay, distfactor); + } + + *newx = x; + *newy = y; + *targetangle = ang; + *grind = gr; +} + +static void P_SpawnSparks(mobj_t *mo, angle_t maindir) +{ + angle_t fa = (mo->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FixedMul(FINECOSINE(fa), mo->radius); + fixed_t s = FixedMul(FINESINE(fa), mo->radius); + mobj_t *spark; + UINT8 b1 = (leveltime % 2 == 1) ? 1 : -1; + UINT8 b2 = ((leveltime / 2) % 2 == 1) ? 1 : -1; + fixed_t r = FRACUNIT*P_RandomRange(-1, 1); + + spark = P_SpawnMobj(mo->x - b2*s + b1*c, mo->y + b2*c + b1*s, mo->z, MT_MINECARTSPARK); + spark->momx = mo->momx + r; + spark->momy = mo->momy + r; + spark->momz = mo->momz + r; + + if (maindir) + { + fixed_t fm = (maindir >> ANGLETOFINESHIFT) & FINEMASK; + spark->momx += 8*FINECOSINE(fm); + spark->momy += 8*FINESINE(fm); + } + P_Thrust(spark, R_PointToAngle2(mo->x, mo->y, spark->x, spark->y), 8*FRACUNIT); + P_SetScale(spark, FRACUNIT/4); + spark->fuse = TICRATE/3; +} + +// Performs a proximity check on a given direction looking for rails. +static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t targetangle, fixed_t xcom, fixed_t ycom) +{ + INT16 interval = 16; + INT16 fwooffset = FixedHypot(mobj->momx, mobj->momy) >> FRACBITS; + fixed_t x = mobj->x; + fixed_t y = mobj->y; + fixed_t z = mobj->z + 40*FRACUNIT; + UINT8 i; + + for (i = 4; i <= 10; i++) + { + fixed_t nz; + size_t lline; + + x += interval*xcom*i + fwooffset*c*i; + y += interval*ycom*i + fwooffset*s*i; + nz = P_FloorzAtPos(x, y, z, mobj->height); + + lline = P_GetMinecartSpecialLine(P_GetMinecartSector(x, y, nz)); + if (lline != -1) + { + fixed_t nx, ny; + angle_t nang, dummy, angdiff; + mobj_t *mark; + mobj_t *snax = P_GetAxis(sides[lines[lline].sidenum[0]].textureoffset >> FRACBITS); + P_GetAxisPosition(x, y, snax, &ny, &nx, &nang, &dummy); + angdiff = nang - targetangle; + if (angdiff < ANG10/2 || angdiff > ANGLE_MAX - ANG10/2) + { + mark = P_SpawnMobj(nx, ny, nz, mobj->info->raisestate); + return mark; + } + } + } + return NULL; +} + +static void P_ParabolicMove(mobj_t *mo, fixed_t x, fixed_t y, fixed_t z, fixed_t gravity, fixed_t speed) +{ + fixed_t dx = x - mo->x; + fixed_t dy = y - mo->y; + fixed_t dz = z - mo->z; + fixed_t dh = P_AproxDistance(dx, dy); + fixed_t c = FixedDiv(dx, dh); + fixed_t s = FixedDiv(dy, dh); + fixed_t fixConst = FixedDiv(speed, gravity); + + mo->momx = FixedMul(c, speed); + mo->momy = FixedMul(s, speed); + mo->momz = FixedDiv(dh, 2*fixConst) + FixedDiv(dz, FixedDiv(dh, fixConst/2)); +} + +static void P_MinecartThink(player_t *player) +{ + mobj_t *minecart = player->mo->tracer; + angle_t fa; + + if (!minecart || !P_MobjWasRemoved(minecart) || !minecart->health) + { + // Minecart died on you, so kill yourself. + P_KillMobj(player->mo, NULL, NULL, 0); + return; + } + +#if 0 + //Limit player's angle to a cone. +#define MINECARTCONEMAX FixedAngle(20*FRACUNIT) + { + angle_t angdiff = player->mo->angle - minecart->angle; + if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX) + player->mo->angle = minecart->angle + MINECARTCONEMAX; + else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) + player->mo->angle = minecart->angle - MINECARTCONEMAX; + + if (angdiff + minecart->angle != player->mo->angle) + { + if (player == &players[consoleplayer]) + localangle = player->mo->angle; + else if (player == &players[secondarydisplayplayer]) + localangle2 = player->mo->angle; + } + } +#endif + + //P_ResetPlayer(player); + + // Player holding jump? + if (player->cmd.buttons & BT_JUMP) + player->pflags |= PF_JUMPDOWN; + else + player->pflags &= ~PF_JUMPDOWN; + + // Handle segments. + P_HandleMinecartSegments(minecart); + + // Force 0 friction. + minecart->friction = FRACUNIT; + + fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; + if (!P_TryMove(minecart, minecart->x + FINECOSINE(fa), minecart->y + FINESINE(fa), true)) + { + P_KillMobj(player->mo, NULL, NULL, 0); + P_KillMobj(minecart, NULL, NULL, 0); + return; + } + + if (P_IsObjectOnGround(minecart)) + { + sector_t *sec; + size_t lnum; + + // Just hit floor. + if (minecart->eflags & MFE_JUSTHITFLOOR) + { + S_StopSound(minecart); + S_StartSound(minecart, sfx_s3k96); + } + + sec = P_GetMinecartSector(minecart->x, minecart->y, minecart->z); + + if (sec) + lnum = P_GetMinecartSpecialLine(sec); + + // Update axis if the cart is standing on a rail. + if (sec && lnum != -1) + { + mobj_t *axis = P_GetAxis(sides[lines[lnum].sidenum[0]].textureoffset >> FRACBITS); + fixed_t newx, newy; + angle_t targetangle, grind; + angle_t prevangle, angdiff; + mobj_t *detleft = NULL; + mobj_t *detright = NULL; + mobj_t *sidelock = NULL; + boolean jumped = false; + fixed_t currentSpeed; + + minecart->movefactor = 0; + P_ResetScore(player); + // Handle angle and position + P_GetAxisPosition(minecart->x, minecart->y, axis, &newx, &newy, &targetangle, &grind); + if (grind) + P_SpawnSparks(minecart, grind); + P_TryMove(minecart, newx, newy, true); + + // Set angle based on target + prevangle = minecart->angle; + angdiff = targetangle - minecart->angle; + if (angdiff < ANGLE_90 + ANG2 || angdiff > ANGLE_270 - ANG2) + minecart->angle = targetangle; + else + minecart->angle = targetangle + ANGLE_180; + player->mo->angle += (minecart->angle - prevangle); // maintain relative angle on turns + if (angdiff + minecart->angle != targetangle) + { + if (player == &players[consoleplayer]) + localangle = player->mo->angle; + else if (player == &players[secondarydisplayplayer]) + localangle2 = player->mo->angle; + } + + // Sideways detection + if (minecart->flags2 & MF2_AMBUSH) + { + angle_t fa = minecart->angle; + fixed_t c = FINECOSINE(fa); + fixed_t s = FINESINE(fa); + + detleft = P_LookForRails(minecart, c, s, targetangle, -s, c); + detright = P_LookForRails(minecart, c, s, targetangle, s, -c); + } + + // How fast are we going? + currentSpeed = FixedHypot(minecart->momx, minecart->momy); + angdiff = R_PointToAngle2(0, 0, minecart->momx, minecart->momy) - minecart->angle; + if (angdiff > ANGLE_90 && angdiff < ANGLE_270) + currentSpeed *= -1; + + // Player-specific behavior. + // Update side hopper marker sprites if pressing strafe. + if (detleft && player->cmd.sidemove < 0) + { + P_SetMobjState(detleft, detleft->info->seestate); + sidelock = detleft; + } + else if (detright && player->cmd.sidemove > 0) + { + P_SetMobjState(detright, detright->info->seestate); + sidelock = detright; + } + + //if (player->cmd.buttons & BT_USE && currentSpeed > 4*FRACUNIT) + // currentSpeed -= FRACUNIT/8; + + // Jumping + if (player->cmd.buttons & BT_JUMP) + { + if (minecart->eflags & MFE_ONGROUND) + minecart->eflags &= ~MFE_ONGROUND; + minecart->z += P_MobjFlip(minecart); + if (sidelock) + P_ParabolicMove(minecart, sidelock->x, sidelock->y, sidelock->z, gravity, max(currentSpeed, 10 * FRACUNIT)); + else + minecart->momz = 10 * FRACUNIT; + + S_StartSound(minecart, sfx_s3k51); + jumped = true; + } + + if (!jumped) + { + // Natural acceleration and boosters + if (currentSpeed < minecart->info->seesound) + currentSpeed += FRACUNIT/4; + + if (minecart->standingslope) + { + fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t front = P_GetZAt(minecart->standingslope, minecart->x, minecart->y); + fixed_t back = P_GetZAt(minecart->standingslope, minecart->x - FINECOSINE(fa), minecart->y - FINESINE(fa)); + + if (abs(front - back) < 3*FRACUNIT) + currentSpeed += (back - front)/3; + } + + // Go forward at our current speed + P_InstaThrust(minecart, minecart->angle, currentSpeed); + + // On-track ka-klong sound FX. + minecart->movecount += abs(currentSpeed); + if (minecart->movecount > 128*FRACUNIT) + { + minecart->movecount %= 128*FRACUNIT; + S_StartSound(minecart, minecart->info->activesound); + } + } + } + else + { + minecart->movefactor++; + if ((P_IsObjectOnGround(minecart) && minecart->movefactor >= 5) // off rail + || (abs(minecart->momx) < minecart->scale/2 && abs(minecart->momy) < minecart->scale/2)) // hit a wall + { + P_KillMobj(player->mo, NULL, NULL, 0); + P_KillMobj(minecart, NULL, NULL, 0); + return; + } + } + } + + P_SetMobjState(player->mo, S_PLAY_STND); + + // Move player to minecart. + P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT); + player->mo->momx = minecart->momx; + player->mo->momy = minecart->momy; + player->mo->momz = 0; + P_TryMove(player->mo, player->mo->x + minecart->momx, player->mo->y + minecart->momy, true); +} + // // P_PlayerThink // @@ -10052,6 +10467,8 @@ void P_PlayerThink(player_t *player) // for a bit after a teleport. if (player->mo->reactiontime) player->mo->reactiontime--; + else if (player->powers[pw_carry] == CR_MINECART) + P_MinecartThink(player); else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_ZOOMTUBE)) { if (player->powers[pw_carry] == CR_ROPEHANG) @@ -10113,7 +10530,15 @@ void P_PlayerThink(player_t *player) switch (player->powers[pw_carry]) { case CR_PLAYER: - player->drawangle = (player->mo->tracer->player ? player->mo->tracer->player->drawangle : player->mo->tracer->angle); + if (player->mo->tracer->player) + { + player->drawangle = player->mo->tracer->player->drawangle; + break; + } + /* FALLTHRU */ + case CR_MINECART: + case CR_GENERIC: + player->drawangle = player->mo->tracer->angle; break; /* -- in case we wanted to have the camera freely movable during zoom tubes case CR_ZOOMTUBE:*/ From cc9d7bee80ce848415d91114a5b491ec22dd3cd5 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 00:04:50 +0200 Subject: [PATCH 21/51] A bunch of bugfixes --- src/p_inter.c | 5 +++-- src/p_mobj.c | 2 +- src/p_user.c | 41 ++++++++++++++++++++--------------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index b474c1a66..7a670e9f6 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1750,8 +1750,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_MINECARTSWITCHPOINT: if (player->powers[pw_carry] == CR_MINECART && toucher->tracer && !P_MobjWasRemoved(toucher->tracer) && toucher->tracer->health) { - boolean destambush = special->flags & MF2_AMBUSH; - if ((toucher->tracer->angle - special->angle + ANGLE_90) >= ANGLE_180) + mobjflag2_t destambush = special->flags2 & MF2_AMBUSH; + angle_t angdiff = toucher->tracer->angle - special->angle; + if (angdiff > ANGLE_90 && angdiff < ANGLE_270) destambush ^= MF2_AMBUSH; toucher->tracer->flags2 = (toucher->tracer->flags2 & ~MF2_AMBUSH) | destambush; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 30f7fc7d4..b7af8eaf6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6749,7 +6749,7 @@ static void P_SpawnMinecartSegments(mobj_t *mobj, boolean mode) seg->extravalue2 = (i == 0) ? 24 : -24; seg->cusval = -90; } - if (mode) + if (!mode) seg->frame &= ~FF_ANIMATE; P_SetTarget(&prevseg->tracer, seg); prevseg = seg; diff --git a/src/p_user.c b/src/p_user.c index 29988c88b..30d1f3fb6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9768,7 +9768,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z) if (!(rover->flags & FF_EXISTS)) continue; - fixed_t fofz = rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; + fixed_t fofz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; if (abs(z - fofz) <= 40*FRACUNIT) { sec = §ors[rover->secnum]; @@ -9782,31 +9782,28 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z) static size_t P_GetMinecartSpecialLine(sector_t *sec) { - size_t line = -1; - if (!sec) return -1; if (sec->tag != 0) - line = P_FindSpecialLineFromTag(16, sec->tag, -1); + return P_FindSpecialLineFromTag(16, sec->tag, -1); // Also try for lines facing the sector itself, with tag 0. - if (line == -1) { UINT32 i; for (i = 0; i < sec->linecount; i++) { line_t *li = sec->lines[i]; if (li->tag == 0 && li->special == 16 && li->frontsector == sec) - line = i; + return li - lines; } } - return line; + return -1; } // Get an axis of a certain ID number -static mobj_t *P_GetAxis(UINT16 num) +static mobj_t *P_GetAxis(INT32 num) { thinker_t *th; mobj_t *mobj; @@ -9823,12 +9820,12 @@ static mobj_t *P_GetAxis(UINT16 num) break; // Skip if this axis isn't the one we want. - if (!mobj->spawnpoint || mobj->spawnpoint->options != num) + if (mobj->health != num) continue; return mobj; } - CONS_Debug(DBG_GAMELOGIC, "P_GetAxis: Track segment %d is missing!\n", num); + CONS_Alert(CONS_WARNING, "P_GetAxis: Track segment %d is missing!\n", num); return NULL; } @@ -9861,17 +9858,11 @@ static void P_GetAxisPosition(fixed_t x, fixed_t y, mobj_t *amo, fixed_t *newx, } else // Keep minecart to circle { - fixed_t rad; - fixed_t distfactor; + fixed_t rad = amo->radius; + fixed_t distfactor = FixedDiv(rad, R_PointToDist2(ax, ay, x, y)); gr = R_PointToAngle2(ax, ay, x, y); ang = gr + ANGLE_90; - if (amo->spawnpoint->angle < 16384) // Counterclockwise - rad = amo->spawnpoint->angle*FRACUNIT; - else // Clockwise - rad = (amo->spawnpoint->angle - 16384)*FRACUNIT; - - distfactor = FixedDiv(rad, R_PointToDist2(ax, ay, x, y)); x = ax + FixedMul(x - ax, distfactor); y = ay + FixedMul(y - ay, distfactor); } @@ -9934,6 +9925,8 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target angle_t nang, dummy, angdiff; mobj_t *mark; mobj_t *snax = P_GetAxis(sides[lines[lline].sidenum[0]].textureoffset >> FRACBITS); + if (!snax) + return NULL; P_GetAxisPosition(x, y, snax, &ny, &nx, &nang, &dummy); angdiff = nang - targetangle; if (angdiff < ANG10/2 || angdiff > ANGLE_MAX - ANG10/2) @@ -9966,7 +9959,7 @@ static void P_MinecartThink(player_t *player) mobj_t *minecart = player->mo->tracer; angle_t fa; - if (!minecart || !P_MobjWasRemoved(minecart) || !minecart->health) + if (!minecart || P_MobjWasRemoved(minecart) || !minecart->health) { // Minecart died on you, so kill yourself. P_KillMobj(player->mo, NULL, NULL, 0); @@ -10045,6 +10038,12 @@ static void P_MinecartThink(player_t *player) boolean jumped = false; fixed_t currentSpeed; + if (!axis) + { + P_KillMobj(player->mo, NULL, NULL, 0); + return; + } + minecart->movefactor = 0; P_ResetScore(player); // Handle angle and position @@ -10072,7 +10071,7 @@ static void P_MinecartThink(player_t *player) // Sideways detection if (minecart->flags2 & MF2_AMBUSH) { - angle_t fa = minecart->angle; + angle_t fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; fixed_t c = FINECOSINE(fa); fixed_t s = FINESINE(fa); @@ -10120,7 +10119,7 @@ static void P_MinecartThink(player_t *player) if (!jumped) { // Natural acceleration and boosters - if (currentSpeed < minecart->info->seesound) + if (currentSpeed < minecart->info->speed) currentSpeed += FRACUNIT/4; if (minecart->standingslope) From 981443c826858b0fb0b396fee9cebf7811bef2ee Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 00:12:58 +0200 Subject: [PATCH 22/51] Another bugfix --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 30d1f3fb6..03d15c390 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9927,7 +9927,7 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target mobj_t *snax = P_GetAxis(sides[lines[lline].sidenum[0]].textureoffset >> FRACBITS); if (!snax) return NULL; - P_GetAxisPosition(x, y, snax, &ny, &nx, &nang, &dummy); + P_GetAxisPosition(x, y, snax, &nx, &ny, &nang, &dummy); angdiff = nang - targetangle; if (angdiff < ANG10/2 || angdiff > ANGLE_MAX - ANG10/2) { From cede95fc21973f1bce0a4075f588ae626293f677 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 00:59:13 +0200 Subject: [PATCH 23/51] Some more bugfixes --- src/p_user.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 03d15c390..619540297 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9782,11 +9782,13 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z) static size_t P_GetMinecartSpecialLine(sector_t *sec) { + size_t line = -1; + if (!sec) - return -1; + return line; if (sec->tag != 0) - return P_FindSpecialLineFromTag(16, sec->tag, -1); + line = P_FindSpecialLineFromTag(16, sec->tag, -1); // Also try for lines facing the sector itself, with tag 0. { @@ -9795,11 +9797,11 @@ static size_t P_GetMinecartSpecialLine(sector_t *sec) { line_t *li = sec->lines[i]; if (li->tag == 0 && li->special == 16 && li->frontsector == sec) - return li - lines; + line = li - lines; } } - return -1; + return line; } // Get an axis of a certain ID number @@ -10165,6 +10167,9 @@ static void P_MinecartThink(player_t *player) player->mo->momy = minecart->momy; player->mo->momz = 0; P_TryMove(player->mo, player->mo->x + minecart->momx, player->mo->y + minecart->momy, true); + + if (player->powers[pw_flashing] == flashingtics) + player->powers[pw_flashing]--; } // From 943ddeeabf58819a291083e44f3833fac283a206 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 13:49:30 +0200 Subject: [PATCH 24/51] You can now jump onto tracks that are running antiparallel to yours --- src/p_user.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 619540297..4a4d25847 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9930,8 +9930,9 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target if (!snax) return NULL; P_GetAxisPosition(x, y, snax, &nx, &ny, &nang, &dummy); - angdiff = nang - targetangle; - if (angdiff < ANG10/2 || angdiff > ANGLE_MAX - ANG10/2) + angdiff = ((nang - targetangle) + ANG10/2) & ~ANGLE_180; + //Axes must be directly parallel or antiparallel, give or take 5 degrees. + if (angdiff < ANG10) { mark = P_SpawnMobj(nx, ny, nz, mobj->info->raisestate); return mark; From a3784850b768962c4649304622c235c44c9852a4 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 13:52:27 +0200 Subject: [PATCH 25/51] Removed an unnecessary tracer check --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 5015e6a79..2655042dc 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -836,7 +836,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_SALOONDOOR && tmthing->player) { - if ((tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->player->mo->tracer && !P_MobjWasRemoved(tmthing->player->mo->tracer))) + if (tmthing->player->powers[pw_carry] == CR_MINECART) { fixed_t dx = tmthing->momx; fixed_t dy = tmthing->momy; From 33ed2924e97d6a44e387d52af852737abf1bcec3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 14:21:27 +0200 Subject: [PATCH 26/51] Fixed minecart not exploding on death --- src/p_inter.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 7a670e9f6..a92cde9f0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2604,13 +2604,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->fuse = TICRATE*2; break; - case MT_MINECART: - A_KillSegments(target); // found in green snapper's code - the minecart segments need hardcode-side support to flash while they have a nonzero fuse - A_Scream(target); - P_SetMobjState(target, S_TNTBARREL_EXPL3); - target->momx = target->momy = target->momz = 0; - break; - case MT_PLAYER: { target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player) @@ -2640,7 +2633,14 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } // Final state setting - do something instead of P_SetMobjState; - if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) + if (target->type == MT_MINECART) + { + A_KillSegments(target); // found in green snapper's code - the minecart segments need hardcode-side support to flash while they have a nonzero fuse + A_Scream(target); + P_SetMobjState(target, S_TNTBARREL_EXPL3); + target->momx = target->momy = target->momz = 0; + } + else if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) { const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90; const fixed_t scale = target->scale; From 91c1e132731841f013bf8b3ca83cab9fcc48987b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 17:33:07 +0200 Subject: [PATCH 27/51] Simplified the setup for the Snapper/minecart death animations --- src/info.c | 22 +++++++++++----------- src/p_enemy.c | 4 +--- src/p_inter.c | 14 ++++++-------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/info.c b/src/info.c index e58a1f3a7..93d6f1b64 100644 --- a/src/info.c +++ b/src/info.c @@ -1067,7 +1067,7 @@ state_t states[NUMSTATES] = {SPR_GSNP, 1, 2, {A_Chase}, 0, 0, S_GSNAPPER3}, // S_GSNAPPER2 {SPR_GSNP, 2, 2, {A_Chase}, 0, 0, S_GSNAPPER4}, // S_GSNAPPER3 {SPR_GSNP, 3, 2, {A_Chase}, 0, 0, S_GSNAPPER1}, // S_GSNAPPER4 - {SPR_GSNP, 0, -1, {A_KillSegments}, 0, 0, S_XPLD_FLICKY}, // S_SNAPPER_XPLD + {SPR_GSNP, 0, 0, {A_KillSegments}, 0, 0, S_XPLD_FLICKY}, // S_SNAPPER_XPLD {SPR_GSNL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_LEG {SPR_GSNL, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_LEGRAISE {SPR_GSNH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNAPPER_HEAD @@ -2428,16 +2428,16 @@ state_t states[NUMSTATES] = {SPR_ADST, 6|FF_ANIMATE, 24, {NULL}, 3, 8, S_NULL}, // S_ARIDDUST3 // Minecart - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_MINECART_IDLE}, // S_MINECART_IDLE - {SPR_NULL, 0, 45, {NULL}, 0, 0, S_NULL}, // S_MINECART_DTH1 - {SPR_MCRT, 8|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTEND - {SPR_MCRT, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_FRONT - {SPR_MCRT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_BACK - {SPR_MCRT, 2|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_LEFT - {SPR_MCRT, 5|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_RIGHT - {SPR_LCKN, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK1 - {SPR_LCKN, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK2 - {SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_MINECART_IDLE}, // S_MINECART_IDLE + {SPR_NULL, 0, 0, {A_KillSegments}, 0, 0, S_TNTBARREL_EXPL3}, // S_MINECART_DTH1 + {SPR_MCRT, 8|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTEND + {SPR_MCRT, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_FRONT + {SPR_MCRT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_BACK + {SPR_MCRT, 2|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_LEFT + {SPR_MCRT, 5|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 2, 3, S_NULL}, // S_MINECARTSEG_RIGHT + {SPR_LCKN, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK1 + {SPR_LCKN, 0|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_MINECARTSIDEMARK2 + {SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK // Saloon door {SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR diff --git a/src/p_enemy.c b/src/p_enemy.c index 235193f9b..b7bb730e1 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13209,7 +13209,7 @@ void A_CanarivoreGas(mobj_t *actor) // // Function: A_KillSegments // -// Description: Causes segments attached via tracer chain to be killed; forces into next state. +// Description: Causes segments attached via tracer chain to be killed. // // var1 = Fuse (if 0, default to TICRATE/2). // var2 = Unused @@ -13236,8 +13236,6 @@ void A_KillSegments(mobj_t *actor) P_Thrust(kseg, R_PointToAngle2(actor->x, actor->y, kseg->x, kseg->y), 3*actor->scale); kseg->momz = 3*actor->scale; } - - P_SetMobjState(actor, actor->state->nextstate); } static void P_SnapperLegPlace(mobj_t *mo) diff --git a/src/p_inter.c b/src/p_inter.c index a92cde9f0..4c2d19297 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2604,6 +2604,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->fuse = TICRATE*2; break; + case MT_MINECART: + A_Scream(target); + target->momx = target->momy = target->momz = 0; + break; + case MT_PLAYER: { target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player) @@ -2633,14 +2638,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } // Final state setting - do something instead of P_SetMobjState; - if (target->type == MT_MINECART) - { - A_KillSegments(target); // found in green snapper's code - the minecart segments need hardcode-side support to flash while they have a nonzero fuse - A_Scream(target); - P_SetMobjState(target, S_TNTBARREL_EXPL3); - target->momx = target->momy = target->momz = 0; - } - else if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) + if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) { const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90; const fixed_t scale = target->scale; From 24c6dd1a6895cb64f992c1454b06a746911b2699 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 20:21:18 +0200 Subject: [PATCH 28/51] Many more bugfixes --- src/p_enemy.c | 1 + src/p_map.c | 6 +++--- src/p_mobj.c | 18 ++++++++++-------- src/p_user.c | 41 ++++++++++++++++++++--------------------- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index b7bb730e1..65581f65a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13547,5 +13547,6 @@ void A_MinecartSparkThink(mobj_t *actor) trail->tics = 2; trail->sprite = actor->sprite; P_SetScale(trail, trail->scale/4); + trail->destscale = trail->scale; } } \ No newline at end of file diff --git a/src/p_map.c b/src/p_map.c index 2655042dc..906ca8c51 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -836,10 +836,10 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_SALOONDOOR && tmthing->player) { - if (tmthing->player->powers[pw_carry] == CR_MINECART) + if (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer) && tmthing->tracer->health) { - fixed_t dx = tmthing->momx; - fixed_t dy = tmthing->momy; + fixed_t dx = tmthing->tracer->momx; + fixed_t dy = tmthing->tracer->momy; fixed_t dm = min(FixedHypot(dx, dy), 16*FRACUNIT); angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle; fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK); diff --git a/src/p_mobj.c b/src/p_mobj.c index b7af8eaf6..4c48db0a6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8567,14 +8567,6 @@ void P_MobjThinker(mobj_t *mobj) } mobj->flags2 ^= MF2_DONTDRAW; break; - case MT_MINECART: - // If player is ded, remove this minecart - if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->health) - { - P_KillMobj(mobj, NULL, NULL, 0); - return; - } - break; case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) { @@ -8952,6 +8944,16 @@ void P_PushableThinker(mobj_t *mobj) if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy)) P_TryMove(mobj, mobj->x, mobj->y, true); + if (mobj->type == MT_MINECART && mobj->health) + { + // If player is ded, remove this minecart + if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->health) + { + P_KillMobj(mobj, NULL, NULL, 0); + return; + } + } + if (mobj->fuse == 1) // it would explode in the MobjThinker code { mobj_t *spawnmo; diff --git a/src/p_user.c b/src/p_user.c index 4a4d25847..c8e5254ea 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9881,23 +9881,21 @@ static void P_SpawnSparks(mobj_t *mo, angle_t maindir) fixed_t c = FixedMul(FINECOSINE(fa), mo->radius); fixed_t s = FixedMul(FINESINE(fa), mo->radius); mobj_t *spark; - UINT8 b1 = (leveltime % 2 == 1) ? 1 : -1; - UINT8 b2 = ((leveltime / 2) % 2 == 1) ? 1 : -1; - fixed_t r = FRACUNIT*P_RandomRange(-1, 1); + SINT8 b1 = (leveltime & 1) ? 1 : -1; + SINT8 b2 = (leveltime & 2) ? 1 : -1; + fixed_t r1 = FRACUNIT*P_RandomRange(-1, 1); + fixed_t r2 = FRACUNIT*P_RandomRange(-1, 1); + fixed_t r3 = FRACUNIT*P_RandomRange(-1, 1); + fixed_t fm = (maindir >> ANGLETOFINESHIFT) & FINEMASK; spark = P_SpawnMobj(mo->x - b2*s + b1*c, mo->y + b2*c + b1*s, mo->z, MT_MINECARTSPARK); - spark->momx = mo->momx + r; - spark->momy = mo->momy + r; - spark->momz = mo->momz + r; + spark->momx = mo->momx + r1 + 8*FINECOSINE(fm); + spark->momy = mo->momy + r2 + 8*FINESINE(fm); + spark->momz = mo->momz + r3; - if (maindir) - { - fixed_t fm = (maindir >> ANGLETOFINESHIFT) & FINEMASK; - spark->momx += 8*FINECOSINE(fm); - spark->momy += 8*FINESINE(fm); - } P_Thrust(spark, R_PointToAngle2(mo->x, mo->y, spark->x, spark->y), 8*FRACUNIT); P_SetScale(spark, FRACUNIT/4); + spark->destscale = spark->scale; spark->fuse = TICRATE/3; } @@ -9979,7 +9977,7 @@ static void P_MinecartThink(player_t *player) else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) player->mo->angle = minecart->angle - MINECARTCONEMAX; - if (angdiff + minecart->angle != player->mo->angle) + if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_AnalogMove(player))) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -10051,7 +10049,7 @@ static void P_MinecartThink(player_t *player) P_ResetScore(player); // Handle angle and position P_GetAxisPosition(minecart->x, minecart->y, axis, &newx, &newy, &targetangle, &grind); - if (grind) + if (axis->type != MT_AXISTRANSFERLINE) P_SpawnSparks(minecart, grind); P_TryMove(minecart, newx, newy, true); @@ -10062,13 +10060,14 @@ static void P_MinecartThink(player_t *player) minecart->angle = targetangle; else minecart->angle = targetangle + ANGLE_180; - player->mo->angle += (minecart->angle - prevangle); // maintain relative angle on turns - if (angdiff + minecart->angle != targetangle) + angdiff = (minecart->angle - prevangle); + if (angdiff && (!demoplayback || P_AnalogMove(player))) // maintain relative angle on turns { + player->mo->angle += angdiff; if (player == &players[consoleplayer]) - localangle = player->mo->angle; + localangle += angdiff; else if (player == &players[secondarydisplayplayer]) - localangle2 = player->mo->angle; + localangle2 += angdiff; } // Sideways detection @@ -10164,9 +10163,9 @@ static void P_MinecartThink(player_t *player) // Move player to minecart. P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT); - player->mo->momx = minecart->momx; - player->mo->momy = minecart->momy; - player->mo->momz = 0; + if (player->powers[pw_carry] != CR_MINECART) + return; + player->mo->momx = player->mo->momy = player->mo->momz = 0; P_TryMove(player->mo, player->mo->x + minecart->momx, player->mo->y + minecart->momy, true); if (player->powers[pw_flashing] == flashingtics) From 8e61cc6d13ada69c420c2bde66b5718bbe7a48d3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 20:59:56 +0200 Subject: [PATCH 29/51] Kill minecarts that fall into death pits --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4c48db0a6..65d8bede6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2580,9 +2580,9 @@ static boolean P_ZMovement(mobj_t *mo) if (!mo->player && P_CheckDeathPitCollide(mo)) { - if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS) + if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS || mo->type == MT_MINECART) { - // Kill enemies and bosses that fall into death pits. + // Kill enemies, bosses and minecarts that fall into death pits. if (mo->health) { P_KillMobj(mo, NULL, NULL, 0); From 39deb64e4fcf491cae46a693a0fac02e8c1b8cd8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 21:43:36 +0200 Subject: [PATCH 30/51] Streamlined the minecart death handling --- src/p_inter.c | 2 ++ src/p_user.c | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 4c2d19297..956a13c2e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2607,6 +2607,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget case MT_MINECART: A_Scream(target); target->momx = target->momy = target->momz = 0; + if (target->target && target->target->health) + P_KillMobj(target->target, target, source, 0); break; case MT_PLAYER: diff --git a/src/p_user.c b/src/p_user.c index c8e5254ea..b44a6f118 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10004,7 +10004,6 @@ static void P_MinecartThink(player_t *player) fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; if (!P_TryMove(minecart, minecart->x + FINECOSINE(fa), minecart->y + FINESINE(fa), true)) { - P_KillMobj(player->mo, NULL, NULL, 0); P_KillMobj(minecart, NULL, NULL, 0); return; } @@ -10041,7 +10040,7 @@ static void P_MinecartThink(player_t *player) if (!axis) { - P_KillMobj(player->mo, NULL, NULL, 0); + P_KillMobj(minecart, NULL, NULL, 0); return; } @@ -10152,7 +10151,6 @@ static void P_MinecartThink(player_t *player) if ((P_IsObjectOnGround(minecart) && minecart->movefactor >= 5) // off rail || (abs(minecart->momx) < minecart->scale/2 && abs(minecart->momy) < minecart->scale/2)) // hit a wall { - P_KillMobj(player->mo, NULL, NULL, 0); P_KillMobj(minecart, NULL, NULL, 0); return; } From 71a25eef9279eae67cbe7d8d7978536bc0fc3485 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 21:58:58 +0200 Subject: [PATCH 31/51] Don't jump repeatedly when holding jump --- src/p_inter.c | 1 + src/p_user.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 956a13c2e..569567379 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1718,6 +1718,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) mcart->friction = FRACUNIT; P_ResetPlayer(player); + player->pflags |= PF_JUMPDOWN; player->powers[pw_carry] = CR_MINECART; toucher->player->pflags &= ~PF_APPLYAUTOBRAKE; P_SetTarget(&toucher->tracer, mcart); diff --git a/src/p_user.c b/src/p_user.c index b44a6f118..5e33d55a4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9990,9 +9990,7 @@ static void P_MinecartThink(player_t *player) //P_ResetPlayer(player); // Player holding jump? - if (player->cmd.buttons & BT_JUMP) - player->pflags |= PF_JUMPDOWN; - else + if (!(player->cmd.buttons & BT_JUMP)) player->pflags &= ~PF_JUMPDOWN; // Handle segments. @@ -10103,8 +10101,10 @@ static void P_MinecartThink(player_t *player) // currentSpeed -= FRACUNIT/8; // Jumping - if (player->cmd.buttons & BT_JUMP) + if ((player->cmd.buttons & BT_JUMP) && !(player->pflags & PF_JUMPDOWN)) { + player->pflags |= PF_JUMPDOWN; + if (minecart->eflags & MFE_ONGROUND) minecart->eflags &= ~MFE_ONGROUND; minecart->z += P_MobjFlip(minecart); From 774ccad4014879d93aa4a97462365c0c1ba5ad17 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 15 Jun 2019 22:29:30 +0200 Subject: [PATCH 32/51] Do death animation even when MF2_DONTDRAW is set --- src/p_inter.c | 3 +++ src/p_mobj.c | 55 ++++++++++++++++++++++++--------------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 569567379..3aed35f84 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3026,6 +3026,9 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) P_ResetPlayer(player); + if (!player->spectator) + player->mo->flags2 &= ~MF2_DONTDRAW; + P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 65d8bede6..776495ccd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7563,38 +7563,35 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_PLAYER: /// \todo Have the player's dead body completely finish its animation even if they've already respawned. - if (!(mobj->flags2 & MF2_DONTDRAW)) - { - if (!mobj->fuse) - { // Go away. - /// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it. - mobj->momz = 0; - if (mobj->player) - mobj->flags2 |= MF2_DONTDRAW; - else // safe to remove, nobody's going to complain! - { - P_RemoveMobj(mobj); - return; - } - } - else // Apply gravity to fall downwards. + if (!mobj->fuse) + { // Go away. + /// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it. + mobj->momz = 0; + if (mobj->player) + mobj->flags2 |= MF2_DONTDRAW; + else // safe to remove, nobody's going to complain! { - if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE)) - { - fixed_t r = mobj->radius>>FRACBITS; - mobj_t *explosion = P_SpawnMobj( - mobj->x + (P_RandomRange(r, -r)<y + (P_RandomRange(r, -r)<z + (P_RandomKey(mobj->height>>FRACBITS)<movedir == DMG_DROWNED) - P_SetObjectMomZ(mobj, -FRACUNIT/2, true); // slower fall from drowning - else - P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + P_RemoveMobj(mobj); + return; } } + else // Apply gravity to fall downwards. + { + if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE)) + { + fixed_t r = mobj->radius >> FRACBITS; + mobj_t *explosion = P_SpawnMobj( + mobj->x + (P_RandomRange(r, -r) << FRACBITS), + mobj->y + (P_RandomRange(r, -r) << FRACBITS), + mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), + MT_BOSSEXPLODE); + S_StartSound(explosion, sfx_cybdth); + } + if (mobj->movedir == DMG_DROWNED) + P_SetObjectMomZ(mobj, -FRACUNIT / 2, true); // slower fall from drowning + else + P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true); + } break; default: break; From b6790c7f35459b27356726f322905312fd0c37f1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 15:35:32 +0200 Subject: [PATCH 33/51] Snapper head/legs and minecart segments flash when they're destroyed --- src/dehacked.c | 1 + src/info.c | 27 +++++++++++++++++++++++++++ src/info.h | 1 + src/p_mobj.c | 6 +++++- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index c546f4431..f70615af6 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7517,6 +7517,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_DUSTLAYER", "MT_ARIDDUST", "MT_MINECART", + "MT_MINECARTSEG", "MT_MINECARTSPAWNER", "MT_MINECARTEND", "MT_MINECARTENDSOLID", diff --git a/src/info.c b/src/info.c index 93d6f1b64..09d2c5184 100644 --- a/src/info.c +++ b/src/info.c @@ -11881,6 +11881,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MT_MINECARTSIDEMARK // raisestate }, + { // MT_MINECARTSEG + -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 + FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags + S_NULL // raisestate + }, + { // MT_MINECARTSPAWNER 1219, // doomednum S_INVISIBLE, // spawnstate diff --git a/src/info.h b/src/info.h index 717f659c9..3e4243bdb 100644 --- a/src/info.h +++ b/src/info.h @@ -4302,6 +4302,7 @@ typedef enum mobj_type MT_DUSTLAYER, MT_ARIDDUST, MT_MINECART, + MT_MINECARTSEG, MT_MINECARTSPAWNER, MT_MINECARTEND, MT_MINECARTENDSOLID, diff --git a/src/p_mobj.c b/src/p_mobj.c index 776495ccd..bfec5af78 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6740,7 +6740,7 @@ static void P_SpawnMinecartSegments(mobj_t *mobj, boolean mode) for (i = 0; i < 4; i++) { - seg = P_SpawnMobj(x, y, z, MT_PARTICLE); + seg = P_SpawnMobj(x, y, z, MT_MINECARTSEG); P_SetMobjState(seg, (statenum_t)(S_MINECARTSEG_FRONT + i)); if (i >= 2) seg->extravalue1 = (i == 2) ? -18 : 18; @@ -8640,6 +8640,10 @@ void P_MobjThinker(mobj_t *mobj) // Check fuse if (mobj->fuse) { + + if (mobj->type == MT_SNAPPER_HEAD || mobj->type == MT_SNAPPER_LEG || mobj->type == MT_MINECARTSEG) + mobj->flags2 ^= MF2_DONTDRAW; + mobj->fuse--; if (!mobj->fuse) { From 622a44f551bb1c1c3c032ac22ddcd88e6685d4a8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 16:39:06 +0200 Subject: [PATCH 34/51] Fixed a bug involving players being thrown out of minecarts --- src/p_inter.c | 3 --- src/p_mobj.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 3aed35f84..0c81d7833 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3660,9 +3660,6 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) } if (player->mo->eflags & MFE_VERTICALFLIP) mo->momz *= -1; - - if (P_IsObjectOnGround(player->mo)) - player->powers[pw_carry] = CR_NONE; } player->losstime += 10*TICRATE; diff --git a/src/p_mobj.c b/src/p_mobj.c index bfec5af78..7163dbe79 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8948,7 +8948,7 @@ void P_PushableThinker(mobj_t *mobj) if (mobj->type == MT_MINECART && mobj->health) { // If player is ded, remove this minecart - if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->health) + if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->health || !mobj->target->player || mobj->target->player->powers[pw_carry] != CR_MINECART) { P_KillMobj(mobj, NULL, NULL, 0); return; From c5a2d33d4e240f13be2dd7f2fe3d91f48d47ffe9 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 16:49:18 +0200 Subject: [PATCH 35/51] Added minecart support to A_MixUp --- src/p_enemy.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 65581f65a..3267965e4 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -6300,6 +6300,10 @@ void A_MixUp(mobj_t *actor) } //get this done first! + if (players[one].powers[pw_carry] == CR_MINECART && players[one].mo->tracer && !(P_MobjWasRemoved(players[one].mo->tracer))) + P_SetTarget(&players[one].mo->tracer->target, players[two].mo); + if (players[two].powers[pw_carry] == CR_MINECART && players[two].mo->tracer && !(P_MobjWasRemoved(players[two].mo->tracer))) + P_SetTarget(&players[two].mo->tracer->target, players[one].mo); tempthing = players[one].mo->tracer; P_SetTarget(&players[one].mo->tracer, players[two].mo->tracer); P_SetTarget(&players[two].mo->tracer, tempthing); @@ -6441,6 +6445,8 @@ void A_MixUp(mobj_t *actor) //...carry after. same reasoning. players[i].powers[pw_carry] = transcarry[teleportfrom]; + if (transcarry[teleportfrom] == CR_MINECART && transtracer[teleportfrom] && !(P_MobjWasRemoved(transtracer[teleportfrom]))) + P_SetTarget(&transtracer[teleportfrom]->target, players[i].mo); teleported[i] = true; counter++; From 7e0c9d9398ec1e074aca0dbbca37e45c828e2fac Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 17:07:13 +0200 Subject: [PATCH 36/51] (Hopefully) fixed the player sometimes landing on the solid part of the minecart stopper after being launched out of the minecart --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 09d2c5184..6e4d38119 100644 --- a/src/info.c +++ b/src/info.c @@ -11985,7 +11985,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SOLID|MF_PAPERCOLLISION, // flags + MF_SOLID|MF_PAPERCOLLISION|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags S_NULL // raisestate }, From fbd7a5ae59b2149eeedec9e43b4309764a94a523 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 17:57:03 +0200 Subject: [PATCH 37/51] Finetuned the saloon door swinging --- src/info.c | 2 +- src/p_map.c | 2 +- src/p_mobj.c | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 6e4d38119..39dcdf654 100644 --- a/src/info.c +++ b/src/info.c @@ -12066,7 +12066,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_s3k90, // activesound - MF_SOLID|MF_NOGRAVITY|MF_RUNSPAWNFUNC|MF_PAPERCOLLISION, // flags + MF_SOLID|MF_NOGRAVITY|MF_RUNSPAWNFUNC|MF_PAPERCOLLISION|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, diff --git a/src/p_map.c b/src/p_map.c index 906ca8c51..abd4174d6 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -844,7 +844,7 @@ static boolean PIT_CheckThing(mobj_t *thing) angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle; fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK); S_StartSound(tmthing, thing->info->activesound); - thing->extravalue2 += FixedMul(s, dm); + thing->extravalue2 += 2*FixedMul(s, dm)/3; return true; } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 7163dbe79..d9210441a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8536,6 +8536,7 @@ void P_MobjThinker(mobj_t *mobj) fixed_t s0 = -96*FINESINE(fa); angle_t fma; fixed_t c, s; + angle_t angdiff; // Adjust angular speed fixed_t da = AngleFixed(mobj->angle - oang); @@ -8546,6 +8547,18 @@ void P_MobjThinker(mobj_t *mobj) // Update angle mobj->angle += FixedAngle(mobj->extravalue2); + angdiff = mobj->angle - FixedAngle(mobj->extravalue1); + if (angdiff > (ANGLE_90 - ANG2) && angdiff < ANGLE_180) + { + mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_90 - ANG2); + mobj->extravalue2 /= 2; + } + else if (angdiff < (ANGLE_270 + ANG2) && angdiff >= ANGLE_180) + { + mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_270 + ANG2); + mobj->extravalue2 /= 2; + } + // Update position fma = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK; c = 48*FINECOSINE(fma); From db7bd4d35ad6b6ba6ab801be4bb75bf1baafc400 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 18:14:15 +0200 Subject: [PATCH 38/51] Fixed the cacti heights --- src/info.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index 39dcdf654..d82de2066 100644 --- a/src/info.c +++ b/src/info.c @@ -11494,7 +11494,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 32*FRACUNIT, // radius - 128*FRACUNIT, // height + 96*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -11521,7 +11521,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius - 132*FRACUNIT, // height + 128*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -11575,7 +11575,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 24*FRACUNIT, // radius - 208*FRACUNIT, // height + 256*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage @@ -11602,7 +11602,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 48*FRACUNIT, // radius - 208*FRACUNIT, // height + 96*FRACUNIT, // height 0, // display offset 100, // mass 0, // damage From 68060b731f00cc6d2f895169d0691f5e9d8c7dfb Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 19:08:20 +0200 Subject: [PATCH 39/51] Fixed a sound bug --- src/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index d82de2066..df8364399 100644 --- a/src/info.c +++ b/src/info.c @@ -2387,7 +2387,7 @@ state_t states[NUMSTATES] = {SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_TNTBARREL_EXPL4}, // S_TNTBARREL_EXPL3 {SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4 {SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5 - {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL6 + {SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL6 {SPR_BARR, 1|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_TNTBARREL_FLYING // TNT proximity shell @@ -5699,7 +5699,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 0, // mass 0, // damage - sfx_s3k8d, // activesound + sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE, // flags S_NULL // raisestate }, @@ -11741,7 +11741,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 100, // mass 0, // damage - sfx_s3k8d, // activesound + sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_ENEMY|MF_PUSHABLE, // flags S_NULL // raisestate }, From cf7e618b2f0ee2911839b7f34877930116e97ee5 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 21:36:22 +0200 Subject: [PATCH 40/51] Fixed a bug with the Canarivore gas --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index d9210441a..34b2be085 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8522,7 +8522,7 @@ void P_MobjThinker(mobj_t *mobj) momz = abs(mobj->momz); if (R_PointToDist2(0, 0, mobj->momx, mobj->momy) < momz) P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), momz); - mobj->flags2 |= MF2_AMBUSH; + mobj->flags2 |= MF2_AMBUSH|MF_NOGRAVITY|MF_NOCLIPHEIGHT; break; } case MT_SALOONDOOR: From e23ef050d51425770ace7101044f891c537ef44d Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 22:00:50 +0200 Subject: [PATCH 41/51] Repaired the height difference check during track switching --- src/p_user.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 5e33d55a4..630864e6f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9753,7 +9753,7 @@ void P_DoPityCheck(player_t *player) } } -static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z) +static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *nz) { sector_t *sec = R_PointInSubsector(x, y)->sector; @@ -9768,15 +9768,20 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z) if (!(rover->flags & FF_EXISTS)) continue; - fixed_t fofz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; - if (abs(z - fofz) <= 40*FRACUNIT) + *nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; + if (abs(z - *nz) <= 40*FRACUNIT) { sec = §ors[rover->secnum]; - break; + return sec; } } } + + *nz = sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight; + if (abs(z - *nz) > 40*FRACUNIT) + return NULL; + return sec; } @@ -9906,7 +9911,7 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target INT16 fwooffset = FixedHypot(mobj->momx, mobj->momy) >> FRACBITS; fixed_t x = mobj->x; fixed_t y = mobj->y; - fixed_t z = mobj->z + 40*FRACUNIT; + fixed_t z = mobj->z; UINT8 i; for (i = 4; i <= 10; i++) @@ -9916,9 +9921,8 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target x += interval*xcom*i + fwooffset*c*i; y += interval*ycom*i + fwooffset*s*i; - nz = P_FloorzAtPos(x, y, z, mobj->height); - lline = P_GetMinecartSpecialLine(P_GetMinecartSector(x, y, nz)); + lline = P_GetMinecartSpecialLine(P_GetMinecartSector(x, y, z, &nz)); if (lline != -1) { fixed_t nx, ny; @@ -10010,6 +10014,7 @@ static void P_MinecartThink(player_t *player) { sector_t *sec; size_t lnum; + fixed_t dummy; // Just hit floor. if (minecart->eflags & MFE_JUSTHITFLOOR) @@ -10018,7 +10023,7 @@ static void P_MinecartThink(player_t *player) S_StartSound(minecart, sfx_s3k96); } - sec = P_GetMinecartSector(minecart->x, minecart->y, minecart->z); + sec = P_GetMinecartSector(minecart->x, minecart->y, minecart->z, &dummy); if (sec) lnum = P_GetMinecartSpecialLine(sec); From 096bad14fbd1a5d8fe1b9c984018ae2f8777782c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 16 Jun 2019 22:26:52 +0200 Subject: [PATCH 42/51] Minecart stopper itself also needs MF_NOCLIPHEIGHT and MF_NOGRAVITY --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index df8364399..d5ce0c523 100644 --- a/src/info.c +++ b/src/info.c @@ -11958,7 +11958,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL, // flags + MF_SPECIAL|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags S_NULL // raisestate }, From 647520e06768faf44176fc9216165cc0341de9b2 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 17 Jun 2019 08:41:51 +0200 Subject: [PATCH 43/51] Adjusted the height difference for track switching --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 630864e6f..a2765e86b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9769,7 +9769,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n continue; *nz = *rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight; - if (abs(z - *nz) <= 40*FRACUNIT) + if (abs(z - *nz) <= 56*FRACUNIT) { sec = §ors[rover->secnum]; return sec; @@ -9779,7 +9779,7 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n } *nz = sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight; - if (abs(z - *nz) > 40*FRACUNIT) + if (abs(z - *nz) > 56*FRACUNIT) return NULL; return sec; From 3634321f439beb371906dcb9827a6cd8a25254f7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 18 Jun 2019 19:06:05 +0200 Subject: [PATCH 44/51] ... --- src/p_mobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 34b2be085..38bc7ed96 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8522,7 +8522,8 @@ void P_MobjThinker(mobj_t *mobj) momz = abs(mobj->momz); if (R_PointToDist2(0, 0, mobj->momx, mobj->momy) < momz) P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), momz); - mobj->flags2 |= MF2_AMBUSH|MF_NOGRAVITY|MF_NOCLIPHEIGHT; + mobj->flags |= MF_NOGRAVITY|MF_NOCLIPHEIGHT; + mobj->flags2 |= MF2_AMBUSH; break; } case MT_SALOONDOOR: From c11a3010d9769c99e7d23b3cd286d8b7e0f3c29a Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 18 Jun 2019 19:29:53 +0200 Subject: [PATCH 45/51] Fixed the Canarivore gas slowdown being much too weak --- src/p_inter.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 0c81d7833..e3e36cf70 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1701,9 +1701,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_CANARIVORE_GAS: // if player and gas touch, attach gas to player (overriding any gas that already attached) and apply slowdown effect - P_TeleportMove(special, toucher->x - toucher->momx / 2, toucher->y - toucher->momy / 2, toucher->z - toucher->momz / 2); - toucher->momx = FixedMul(toucher->momx, 50 * FRACUNIT / 51); - toucher->momy = FixedMul(toucher->momy, 50 * FRACUNIT / 51); + P_UnsetThingPosition(special); + special->x = toucher->x - toucher->momx/2; + special->y = toucher->y - toucher->momy/2; + special->z = toucher->z - toucher->momz/2; + P_SetThingPosition(special); + toucher->momx = FixedMul(toucher->momx, 50*FRACUNIT/51); + toucher->momy = FixedMul(toucher->momy, 50*FRACUNIT/51); special->momx = toucher->momx; special->momy = toucher->momy; special->momz = toucher->momz; From d388547021280b8d3bd568b017e35193da4bef59 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 19 Jun 2019 00:10:28 +0200 Subject: [PATCH 46/51] Some more minecart fixes --- src/p_inter.c | 8 ++++++-- src/p_user.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index e3e36cf70..0fab3353c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1743,12 +1743,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2; P_ResetPlayer(player); player->pflags &= ~PF_APPLYAUTOBRAKE; - P_SetMobjState(toucher, S_PLAY_FALL); + P_SetPlayerMobjState(toucher, S_PLAY_FALL); P_SetTarget(&toucher->tracer->target, NULL); P_KillMobj(toucher->tracer, toucher, special, 0); P_SetTarget(&toucher->tracer, NULL); player->powers[pw_carry] = CR_NONE; - P_TeleportMove(toucher, special->x, special->y, maxz); + P_UnsetThingPosition(toucher); + toucher->x = special->x; + toucher->y = special->y; + toucher->z = maxz; + P_SetThingPosition(toucher); } return; diff --git a/src/p_user.c b/src/p_user.c index a2765e86b..8764fc9fb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10162,7 +10162,7 @@ static void P_MinecartThink(player_t *player) } } - P_SetMobjState(player->mo, S_PLAY_STND); + P_SetPlayerMobjState(player->mo, S_PLAY_STND); // Move player to minecart. P_TeleportMove(player->mo, minecart->x - minecart->momx, minecart->y - minecart->momy, minecart->z + max(minecart->momz, 0) + 8*FRACUNIT); From f7a32835d54effbd22a1c76c40cc304d9f8a8dd2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 20 Jun 2019 20:05:07 +0100 Subject: [PATCH 47/51] Fix warnings/errors found during compiling, mostly of the mixed-declaration-and-code or shadowed variables variety --- src/p_enemy.c | 7 ++++--- src/p_user.c | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 3267965e4..4123d316c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5189,6 +5189,7 @@ void A_MinusDigging(mobj_t *actor) fixed_t x = FINECOSINE(fa)*dis + actor->x + FRACUNIT*P_RandomRange(-rad, rad); fixed_t y = FINESINE(fa)*dis + actor->y + FRACUNIT*P_RandomRange(-rad, rad); fixed_t mz = (actor->eflags & MFE_VERTICALFLIP) ? actor->ceilingz : actor->floorz; + mobj_t *par; #ifdef HAVE_BLUA if (LUA_CallAction("A_MinusDigging", actor)) @@ -5201,7 +5202,7 @@ void A_MinusDigging(mobj_t *actor) return; } - mobj_t *par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); + par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); if (actor->eflags & MFE_VERTICALFLIP) par->eflags |= MFE_VERTICALFLIP; P_TryMove(par, x, y, false); @@ -5214,7 +5215,7 @@ void A_MinusDigging(mobj_t *actor) S_StartSound(actor, actor->info->attacksound); // Spawn growing dirt pile. - mobj_t *par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); + par = P_SpawnMobj(actor->x, actor->y, mz, MT_MINUSDIRT); P_SetMobjState(par, actor->info->raisestate); P_SetScale(par, actor->scale*2); if (actor->eflags & MFE_VERTICALFLIP) @@ -5313,7 +5314,7 @@ void A_MinusCheck(mobj_t *actor) if (((actor->eflags & MFE_VERTICALFLIP) && actor->z + actor->height >= actor->ceilingz) || (!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz)) { - P_SetMobjState(actor, locvar1 ? locvar1 : actor->info->seestate); + P_SetMobjState(actor, locvar1 ? (statenum_t)locvar1 : actor->info->seestate); actor->flags = actor->info->flags; } } diff --git a/src/p_user.c b/src/p_user.c index 8764fc9fb..997adda6e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9785,9 +9785,9 @@ static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *n return sec; } -static size_t P_GetMinecartSpecialLine(sector_t *sec) +static INT32 P_GetMinecartSpecialLine(sector_t *sec) { - size_t line = -1; + INT32 line = -1; if (!sec) return line; @@ -9917,7 +9917,7 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target for (i = 4; i <= 10; i++) { fixed_t nz; - size_t lline; + INT32 lline; x += interval*xcom*i + fwooffset*c*i; y += interval*ycom*i + fwooffset*s*i; @@ -9944,7 +9944,7 @@ static mobj_t *P_LookForRails(mobj_t* mobj, fixed_t c, fixed_t s, angle_t target return NULL; } -static void P_ParabolicMove(mobj_t *mo, fixed_t x, fixed_t y, fixed_t z, fixed_t gravity, fixed_t speed) +static void P_ParabolicMove(mobj_t *mo, fixed_t x, fixed_t y, fixed_t z, fixed_t g, fixed_t speed) { fixed_t dx = x - mo->x; fixed_t dy = y - mo->y; @@ -9952,7 +9952,7 @@ static void P_ParabolicMove(mobj_t *mo, fixed_t x, fixed_t y, fixed_t z, fixed_t fixed_t dh = P_AproxDistance(dx, dy); fixed_t c = FixedDiv(dx, dh); fixed_t s = FixedDiv(dy, dh); - fixed_t fixConst = FixedDiv(speed, gravity); + fixed_t fixConst = FixedDiv(speed, g); mo->momx = FixedMul(c, speed); mo->momy = FixedMul(s, speed); @@ -10013,7 +10013,7 @@ static void P_MinecartThink(player_t *player) if (P_IsObjectOnGround(minecart)) { sector_t *sec; - size_t lnum; + INT32 lnum; fixed_t dummy; // Just hit floor. @@ -10075,9 +10075,9 @@ static void P_MinecartThink(player_t *player) // Sideways detection if (minecart->flags2 & MF2_AMBUSH) { - angle_t fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t c = FINECOSINE(fa); - fixed_t s = FINESINE(fa); + angle_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c = FINECOSINE(fa2); + fixed_t s = FINESINE(fa2); detleft = P_LookForRails(minecart, c, s, targetangle, -s, c); detright = P_LookForRails(minecart, c, s, targetangle, s, -c); @@ -10130,9 +10130,9 @@ static void P_MinecartThink(player_t *player) if (minecart->standingslope) { - fa = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t fa2 = (minecart->angle >> ANGLETOFINESHIFT) & FINEMASK; fixed_t front = P_GetZAt(minecart->standingslope, minecart->x, minecart->y); - fixed_t back = P_GetZAt(minecart->standingslope, minecart->x - FINECOSINE(fa), minecart->y - FINESINE(fa)); + fixed_t back = P_GetZAt(minecart->standingslope, minecart->x - FINECOSINE(fa2), minecart->y - FINESINE(fa2)); if (abs(front - back) < 3*FRACUNIT) currentSpeed += (back - front)/3; From 28abc883bebde96c86a7e975df9c697d6ee0d174 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 21 Jun 2019 20:13:30 +0200 Subject: [PATCH 48/51] By popular demand: Track switching only requires strafe instead of jump+strafe --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 997adda6e..5430f30a8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10106,7 +10106,7 @@ static void P_MinecartThink(player_t *player) // currentSpeed -= FRACUNIT/8; // Jumping - if ((player->cmd.buttons & BT_JUMP) && !(player->pflags & PF_JUMPDOWN)) + if (sidelock || ((player->cmd.buttons & BT_JUMP) && !(player->pflags & PF_JUMPDOWN))) { player->pflags |= PF_JUMPDOWN; From ed7a109ce93d5d109b3cbddddbcca364ee49fc49 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 21 Jun 2019 23:34:49 +0200 Subject: [PATCH 49/51] Also back by popular demand: Restricting the camera angle during a minecart ride --- src/p_user.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 5430f30a8..248cef08a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9971,7 +9971,6 @@ static void P_MinecartThink(player_t *player) return; } -#if 0 //Limit player's angle to a cone. #define MINECARTCONEMAX FixedAngle(20*FRACUNIT) { @@ -9989,9 +9988,6 @@ static void P_MinecartThink(player_t *player) localangle2 = player->mo->angle; } } -#endif - - //P_ResetPlayer(player); // Player holding jump? if (!(player->cmd.buttons & BT_JUMP)) @@ -10475,7 +10471,12 @@ void P_PlayerThink(player_t *player) if (player->mo->reactiontime) player->mo->reactiontime--; else if (player->powers[pw_carry] == CR_MINECART) + { + if (!P_AnalogMove(player)) + player->mo->angle = (cmd->angleturn << 16 /* not FRACBITS */); + P_MinecartThink(player); + } else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_ZOOMTUBE)) { if (player->powers[pw_carry] == CR_ROPEHANG) From 4385e07c0b5d295ed7338f9920df53b98cb7313e Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 21 Jun 2019 23:40:28 +0200 Subject: [PATCH 50/51] Always use the white sidemark sprite, since track switching is no longer "activated" --- src/info.c | 4 ++-- src/p_user.c | 7 ------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/info.c b/src/info.c index d5ce0c523..a585da74e 100644 --- a/src/info.c +++ b/src/info.c @@ -11991,9 +11991,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_MINECARTSIDEMARK -1, // doomednum - S_MINECARTSIDEMARK1, // spawnstate + S_MINECARTSIDEMARK2, // spawnstate 1, // spawnhealth - S_MINECARTSIDEMARK2, // seestate + S_NULL, // seestate sfx_None, // seesound 0, // reactiontime sfx_None, // attacksound diff --git a/src/p_user.c b/src/p_user.c index 248cef08a..ed638dd3a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10086,17 +10086,10 @@ static void P_MinecartThink(player_t *player) currentSpeed *= -1; // Player-specific behavior. - // Update side hopper marker sprites if pressing strafe. if (detleft && player->cmd.sidemove < 0) - { - P_SetMobjState(detleft, detleft->info->seestate); sidelock = detleft; - } else if (detright && player->cmd.sidemove > 0) - { - P_SetMobjState(detright, detright->info->seestate); sidelock = detright; - } //if (player->cmd.buttons & BT_USE && currentSpeed > 4*FRACUNIT) // currentSpeed -= FRACUNIT/8; From 287c25b8f96c941c99c24d71097d111b09855869 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 21 Jun 2019 23:42:48 +0200 Subject: [PATCH 51/51] Forgot to copy something over from the CR_ROPEHANG case --- src/p_user.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index ed638dd3a..54ca6c78c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10468,6 +10468,10 @@ void P_PlayerThink(player_t *player) if (!P_AnalogMove(player)) player->mo->angle = (cmd->angleturn << 16 /* not FRACBITS */); + ticruned++; + if ((cmd->angleturn & TICCMD_RECEIVED) == 0) + ticmiss++; + P_MinecartThink(player); } else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_ZOOMTUBE))