From d92ccf68237eedbb185d1af2ef07ab8ff8e63c9b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 2 May 2019 18:01:18 +0100 Subject: [PATCH 01/38] Hardcoded all the main Fang-specific object types, states and sprites. This cannot be compiled as-is right now for the following reasons: * Numerous actions still need to be hardcoded. * MT_FBOMB uses the TNT barrel explosion (and by extention A_TNTExplode) for its death state. This is a pickle, I'll deal with it when I get to it. Also missing: * Fang waypoint object type+states. * Fang's good looks (to be put in the resource files obviously). * Fang's brain. --- src/dehacked.c | 83 ++++++++++++++++++++ src/info.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++- src/info.h | 87 ++++++++++++++++++++- 3 files changed, 375 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 54dfc441e..4aba5c495 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4530,6 +4530,83 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_JETFLAME1", "S_JETFLAME2", + // Boss 5 + "S_FANG_IDLE1", + "S_FANG_IDLE2", + "S_FANG_IDLE3", + "S_FANG_IDLE4", + "S_FANG_IDLE5", + "S_FANG_IDLE6", + "S_FANG_IDLE7", + "S_FANG_IDLE8", + "S_FANG_PAIN1", + "S_FANG_PAIN2", + "S_FANG_PATHINGSTART1", + "S_FANG_PATHINGSTART2", + "S_FANG_PATHING", + "S_FANG_BOUNCE1", + "S_FANG_BOUNCE2", + "S_FANG_BOUNCE3", + "S_FANG_BOUNCE4", + "S_FANG_FALL1", + "S_FANG_FALL2", + "S_FANG_SLIDE", + "S_FANG_CHECKPATH1", + "S_FANG_CHECKPATH2", + "S_FANG_PATHINGCONT1", + "S_FANG_PATHINGCONT2", + "S_FANG_PATHINGCONT3", + "S_FANG_SKID1", + "S_FANG_SKID2", + "S_FANG_SKID3", + "S_FANG_CHOOSEATTACK", + "S_FANG_FIRESTART1", + "S_FANG_FIRESTART2", + "S_FANG_FIRE1", + "S_FANG_FIRE2", + "S_FANG_FIRE3", + "S_FANG_FIRE4", + "S_FANG_FIREREPEAT", + "S_FANG_LOBSHOT1", + "S_FANG_LOBSHOT2", + "S_FANG_WAIT1", + "S_FANG_WAIT2", + "S_FANG_WALLHIT", + "S_FANG_PINCHPATHINGSTART1", + "S_FANG_PINCHPATHINGSTART2", + "S_FANG_PINCHPATHING", + "S_FANG_PINCHBOUNCE1", + "S_FANG_PINCHBOUNCE2", + "S_FANG_PINCHBOUNCE3", + "S_FANG_PINCHBOUNCE4", + "S_FANG_PINCHFALL1", + "S_FANG_PINCHFALL2", + "S_FANG_PINCHSKID1", + "S_FANG_PINCHSKID2", + "S_FANG_PINCHLOBSHOT1", + "S_FANG_PINCHLOBSHOT2", + "S_FANG_PINCHLOBSHOT3", + "S_FANG_PINCHLOBSHOT4", + "S_FANG_DIE1", + "S_FANG_DIE2", + "S_FANG_DIE3", + "S_FANG_DIE4", + "S_FANG_DIE5", + "S_FANG_DIE6", + "S_FANG_DIE7", + "S_FANG_DIE8", + "S_FANG_FLEEPATHING1", + "S_FANG_FLEEPATHING2", + "S_FANG_FLEEBOUNCE1", + "S_FANG_FLEEBOUNCE2", + "S_FANG_KO", + + "S_FBOMB1", + "S_FBOMB2", + "S_FSGNA", + "S_FSGNB", + "S_FSGNC", + // Black Eggman (Boss 7) "S_BLACKEGG_STND", "S_BLACKEGG_STND2", @@ -6820,6 +6897,12 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_EGGMOBILE4_MACE", "MT_JETFLAME", + // Boss 5 + "MT_FANG", + "MT_FBOMB", + "MT_FSGNA", + "MT_FSGNB", + // Black Eggman (Boss 7) "MT_BLACKEGGMAN", "MT_BLACKEGGMAN_HELPER", diff --git a/src/info.c b/src/info.c index 86e40c388..e2f4c9246 100644 --- a/src/info.c +++ b/src/info.c @@ -87,7 +87,9 @@ char sprnames[NUMSPRITES + 1][5] = "EFIR", // Boss 4 jet flame // Boss 5 (Arid Canyon) - "EGGQ", + "FANG", // replaces EGGQ + "FBOM", + "FSGN", // Boss 6 (Red Volcano) "EGGR", @@ -1315,6 +1317,101 @@ state_t states[NUMSTATES] = {SPR_EFIR, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_JETFLAME2}, // S_JETFLAME1 {SPR_EFIR, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_JETFLAME1}, // S_JETFLAME2 + // Boss 5 + {SPR_FANG, 2, 16, {A_Look}, 1, 0, S_FANG_IDLE2}, // S_FANG_IDLE1 + {SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE3}, // S_FANG_IDLE2 + {SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE4}, // S_FANG_IDLE3 + {SPR_FANG, 3, 16, {A_Look}, 1, 0, S_FANG_IDLE5}, // S_FANG_IDLE4 + {SPR_FANG, 2, 16, {A_Look}, 1, 0, S_FANG_IDLE6}, // S_FANG_IDLE5 + {SPR_FANG, 1, 16, {A_Look}, 1, 0, S_FANG_IDLE7}, // S_FANG_IDLE6 + {SPR_FANG, 1, 16, {A_Look}, 1, 0, S_FANG_IDLE8}, // S_FANG_IDLE7 + {SPR_FANG, 1, 16, {A_Look}, 1, 0, S_FANG_IDLE1}, // S_FANG_IDLE8 + + {SPR_FANG, 14, 0, {A_DoNPCPain}, FRACUNIT, 0, S_FANG_PAIN2}, // S_FANG_PAIN1 + {SPR_FANG, 14, 1, {A_Boss5CheckOnGround}, S_FANG_PATHINGSTART1, S_FANG_PINCHPATHINGSTART1, S_FANG_PAIN2}, // S_FANG_PAIN2 + + {SPR_FANG, 8, 0, {A_Boss5ExtraRepeat}, 5, 4, S_FANG_PATHINGSTART2}, // S_FANG_PATHINGSTART1 + {SPR_FANG, 8, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PATHING}, // S_FANG_PATHINGSTART2 + {SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 0, 0, S_FANG_BOUNCE1}, // S_FANG_PATHING + + {SPR_FANG, 8, 2, {A_Thrust}, 0, 1, S_FANG_BOUNCE2}, // S_FANG_BOUNCE1 + {SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_BOUNCE3}, // S_FANG_BOUNCE2 + {SPR_FANG, 10, 1, {A_Boss5Jump}, 0, 0, S_FANG_BOUNCE4}, // S_FANG_BOUNCE3 + {SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_CHECKPATH1, S_FANG_FALL1, S_FANG_BOUNCE4}, // S_FANG_BOUNCE4 + + {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_CHECKPATH1, 0, S_FANG_FALL2}, // S_FANG_FALL1 + {SPR_FANG, 13, 1, {A_Boss5CheckOnGround}, S_FANG_CHECKPATH1, 0, S_FANG_FALL1}, // S_FANG_FALL2 + + {SPR_FANG, 8, 0, {A_Boss5Calm}, 0, 0, S_FANG_CHECKPATH2}, // S_FANG_CHECKPATH1 + {SPR_FANG, 8, 0, {A_Repeat}, 0, S_FANG_PATHINGCONT1, S_FANG_SKID1}, // S_FANG_CHECKPATH2 + + {SPR_FANG, 9, 0, {A_Boss5PinchShot}, MT_FBOMB, -16, S_FANG_PATHINGCONT2}, // S_FANG_PATHINGCONT1 + {SPR_FANG, 9, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PATHINGCONT3}, // S_FANG_PATHINGCONT2 + {SPR_FANG, 9, 2, {A_Thrust}, 0, 1, S_FANG_PATHING}, // S_FANG_PATHINGCONT3 + + {SPR_FANG, 4, 0, {A_PlayAttackSound}, 0, 0, S_FANG_SKID2}, // S_FANG_SKID1 + {SPR_FANG, 4, 1, {A_DoNPCSkid}, S_FANG_SKID3, 0, S_FANG_SKID2}, // S_FANG_SKID2 + {SPR_FANG, 4, 10, {NULL}, 0, 0, S_FANG_CHOOSEATTACK}, // S_FANG_SKID3 + + {SPR_FANG, 0, 0, {A_RandomState}, S_FANG_LOBSHOT1, S_FANG_FIRESTART1, S_NULL}, // S_FANG_CHOOSEATTACK + + {SPR_FANG, 5, 0, {A_PrepareRepeat}, 3, 0, S_FANG_FIRESTART2}, // S_FANG_FIRESTART1 // Reset loop + {SPR_FANG, 5, 18, {A_LookForBetter}, 1, 0, S_FANG_FIRE1}, // S_FANG_FIRESTART2 + {SPR_FANG, 5, 5, {A_FireShot}, MT_CORK, -16, S_FANG_FIRE2}, // S_FANG_FIRE1 // Start of loop + {SPR_FANG, 6, 5, {NULL}, 0, 0, S_FANG_FIRE3}, // S_FANG_FIRE2 + {SPR_FANG, 7, 5, {NULL}, 0, 0, S_FANG_FIRE4}, // S_FANG_FIRE3 + {SPR_FANG, 5, 5, {NULL}, 2, 0, S_FANG_FIREREPEAT}, // S_FANG_FIRE4 + {SPR_FANG, 5, 0, {A_Repeat}, 3, S_FANG_FIRE1, S_FANG_WAIT1}, // S_FANG_FIREREPEAT // End of loop + + {SPR_FANG, 19, 18, {A_LookForBetter}, 1, 0, S_FANG_LOBSHOT2}, // S_FANG_LOBSHOT1 + {SPR_FANG, 20, 18, {A_BrakLobShot}, MT_FBOMB, 32+FRACUNIT, S_FANG_WAIT1}, // S_FANG_LOBSHOT2 + + {SPR_FANG, FF_ANIMATE|15, 70, {NULL}, 1, 5, S_FANG_WAIT2}, // S_FANG_WAIT1 + {SPR_FANG, 0, 35, {A_Look}, 1, 0, S_FANG_IDLE1}, // S_FANG_WAIT2 + + {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_PATHINGSTART2, S_FANG_PINCHPATHINGSTART1, S_FANG_WALLHIT}, // S_FANG_WALLHIT + + {SPR_FANG, 8, 0, {A_PrepareRepeat}, 1, 0, S_FANG_PINCHPATHINGSTART2}, // S_FANG_PINCHPATHINGSTART1 + {SPR_FANG, 8, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PINCHPATHING}, // S_FANG_PINCHPATHINGSTART2 + {SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 1, 0, S_FANG_PINCHBOUNCE1}, // S_FANG_PINCHPATHING + {SPR_FANG, 8, 2, {A_Thrust}, 0, 1, S_FANG_PINCHBOUNCE2}, // S_FANG_PINCHBOUNCE1 + {SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_PINCHBOUNCE3}, // S_FANG_PINCHBOUNCE2 + {SPR_FANG, 10, 2, {A_Boss5Jump}, 0, 0, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE3 + {SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_PINCHSKID1, S_FANG_PINCHFALL1, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE4 + {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL2}, // S_FANG_PINCHFALL1 + {SPR_FANG, 13, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL1}, // S_FANG_PINCHFALL2 + {SPR_FANG, 4, 0, {A_PlayAttackSound}, 0, 0, S_FANG_PINCHSKID2}, // S_FANG_PINCHSKID1 + {SPR_FANG, 4, 1, {A_DoNPCSkid}, S_FANG_PINCHLOBSHOT1, 0, S_FANG_PINCHSKID2}, // S_FANG_PINCHSKID2 + {SPR_FANG, 19, 18, {A_FaceTarget}, 3, 0, S_FANG_PINCHLOBSHOT2}, // S_FANG_PINCHLOBSHOT1 + {SPR_FANG, 20, 30, {A_Boss5MakeItRain}, MT_FBOMB, -16, S_FANG_PINCHLOBSHOT3}, // S_FANG_PINCHLOBSHOT2 + {SPR_FANG, 19, 18, {A_LinedefExecute}, LE_BOSS4DROP, 0, S_FANG_PINCHLOBSHOT4}, // S_FANG_PINCHLOBSHOT3 + {SPR_FANG, 19, 0, {A_Boss5Calm}, 0, 0, S_FANG_PATHINGSTART1}, // S_FANG_PINCHLOBSHOT4 + + {SPR_FANG, 14, 0, {A_DoNPCPain}, 0, 0, S_FANG_DIE2}, // S_FANG_DIE1 + {SPR_FANG, 14, 1, {A_Boss5CheckOnGround}, S_FANG_DIE3, 0, S_FANG_DIE2}, // S_FANG_DIE2 + + {SPR_FANG, 17, 0, {A_Scream}, 0, 0, S_FANG_DIE4}, // S_FANG_DIE3 + {SPR_FANG, 17, 104, {NULL}, 0, 0, S_FANG_DIE5}, // S_FANG_DIE4 + + {SPR_FANG, 11, 0, {A_PlaySound}, sfx_jump, 0, S_FANG_DIE6}, // S_FANG_DIE5 + {SPR_FANG, 11, 1, {A_ZThrust}, 6, FRACUNIT|1, S_FANG_DIE7}, // S_FANG_DIE6 + {SPR_FANG, 11, 1, {A_Boss5CheckFalling}, S_FANG_FLEEPATHING1, S_FANG_DIE8, S_FANG_DIE7}, // S_FANG_DIE7 + {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_FLEEPATHING1, 0, S_FANG_DIE8}, // S_FANG_DIE8 + + {SPR_FANG, 9, 0, {A_PlayActiveSound}, 0, 0, S_FANG_FLEEPATHING2}, // S_FANG_FLEEPATHING1 + {SPR_FANG, 8, 2, {A_Boss5FindWaypoint}, 2, 0, S_FANG_FLEEBOUNCE1}, // S_FANG_FLEEPATHING2 + {SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_FLEEBOUNCE2}, // S_FANG_FLEEBOUNCE1 + {SPR_FANG, 10, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_FANG_FLEEBOUNCE2 + + {SPR_FANG, 18, 7*TICRATE, {NULL}, 0, 0, S_NULL}, // S_FANG_KO + + {SPR_FBOM, 0, 1, {A_GhostMe}, 0, 0, S_FBOMB2}, // S_FBOMB1 + {SPR_FBOM, 1, 1, {A_GhostMe}, 0, 0, S_FBOMB1}, // S_FBOMB2 + {SPR_FSGN, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNA + {SPR_FSGN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNB + {SPR_FSGN, 2|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNC + + // Black Eggman (Boss 7) {SPR_BRAK, 0, 1, {A_SetReactionTime}, 0, 0, S_BLACKEGG_STND2}, // S_BLACKEGG_STND {SPR_BRAK, 0, 7, {A_Look}, 1, 0, S_BLACKEGG_STND2}, // S_BLACKEGG_STND2 {SPR_BRAK, 1, 7, {NULL}, 0, 0, S_BLACKEGG_WALK2}, // S_BLACKEGG_WALK1 @@ -5248,6 +5345,114 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_FANG + 204, // doomednum + S_FANG_IDLE1, // spawnstate + 8, // spawnhealth + S_FANG_PATHINGSTART1, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_skid, // attacksound + S_FANG_PAIN1, // painstate + 0, // painchance + sfx_s3k5d, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_FANG_DIE1, // deathstate + S_FANG_KO, // xdeathstate + sfx_s3k90, // deathsound + 0, // speed + 24*FRACUNIT, // radius + 60*FRACUNIT, // height + 0, // display offset + 0, // mass + 3, // damage + sfx_boingf, // activesound + MF_SPECIAL|MF_BOSS|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_FBOMB + -1, // doomednum + S_FBOMB1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_s3k51, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_TNTBARREL_EXPL1, // deathstate + S_NULL, // xdeathstate + sfx_s3k4e, // deathsound + 20*FRACUNIT, // speed + 24*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_s3k8d, // activesound + MF_NOBLOCKMAP|MF_MISSILE, // flags + S_NULL // raisestate + }, + + { // MT_FSGNA + -1, // doomednum + S_FSGNA, // 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_mspogo, // deathsound + 0, // speed + 124*FRACUNIT, // radius + 124*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_FSGNB + -1, // doomednum + S_FSGNB, // 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_FSGNC, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 124*FRACUNIT, // radius + 640*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY|MF_SOLID, // flags + S_NULL // raisestate + }, + { // MT_BLACKEGGMAN 206, // doomednum S_BLACKEGG_STND, // spawnstate diff --git a/src/info.h b/src/info.h index 962a6be29..932c82573 100644 --- a/src/info.h +++ b/src/info.h @@ -306,7 +306,9 @@ typedef enum sprite SPR_EFIR, // Boss 4 jet flame // Boss 5 (Arid Canyon) - SPR_EGGQ, + SPR_FANG, // replaces EGGQ + SPR_FBOM, + SPR_FSGN, // Boss 6 (Red Volcano) SPR_EGGR, @@ -1442,6 +1444,83 @@ typedef enum state S_JETFLAME1, S_JETFLAME2, + // Boss 5 + S_FANG_IDLE1, + S_FANG_IDLE2, + S_FANG_IDLE3, + S_FANG_IDLE4, + S_FANG_IDLE5, + S_FANG_IDLE6, + S_FANG_IDLE7, + S_FANG_IDLE8, + S_FANG_PAIN1, + S_FANG_PAIN2, + S_FANG_PATHINGSTART1, + S_FANG_PATHINGSTART2, + S_FANG_PATHING, + S_FANG_BOUNCE1, + S_FANG_BOUNCE2, + S_FANG_BOUNCE3, + S_FANG_BOUNCE4, + S_FANG_FALL1, + S_FANG_FALL2, + S_FANG_SLIDE, + S_FANG_CHECKPATH1, + S_FANG_CHECKPATH2, + S_FANG_PATHINGCONT1, + S_FANG_PATHINGCONT2, + S_FANG_PATHINGCONT3, + S_FANG_SKID1, + S_FANG_SKID2, + S_FANG_SKID3, + S_FANG_CHOOSEATTACK, + S_FANG_FIRESTART1, + S_FANG_FIRESTART2, + S_FANG_FIRE1, + S_FANG_FIRE2, + S_FANG_FIRE3, + S_FANG_FIRE4, + S_FANG_FIREREPEAT, + S_FANG_LOBSHOT1, + S_FANG_LOBSHOT2, + S_FANG_WAIT1, + S_FANG_WAIT2, + S_FANG_WALLHIT, + S_FANG_PINCHPATHINGSTART1, + S_FANG_PINCHPATHINGSTART2, + S_FANG_PINCHPATHING, + S_FANG_PINCHBOUNCE1, + S_FANG_PINCHBOUNCE2, + S_FANG_PINCHBOUNCE3, + S_FANG_PINCHBOUNCE4, + S_FANG_PINCHFALL1, + S_FANG_PINCHFALL2, + S_FANG_PINCHSKID1, + S_FANG_PINCHSKID2, + S_FANG_PINCHLOBSHOT1, + S_FANG_PINCHLOBSHOT2, + S_FANG_PINCHLOBSHOT3, + S_FANG_PINCHLOBSHOT4, + S_FANG_DIE1, + S_FANG_DIE2, + S_FANG_DIE3, + S_FANG_DIE4, + S_FANG_DIE5, + S_FANG_DIE6, + S_FANG_DIE7, + S_FANG_DIE8, + S_FANG_FLEEPATHING1, + S_FANG_FLEEPATHING2, + S_FANG_FLEEBOUNCE1, + S_FANG_FLEEBOUNCE2, + S_FANG_KO, + + S_FBOMB1, + S_FBOMB2, + S_FSGNA, + S_FSGNB, + S_FSGNC, + // Black Eggman (Boss 7) S_BLACKEGG_STND, S_BLACKEGG_STND2, @@ -3752,6 +3831,12 @@ typedef enum mobj_type MT_EGGMOBILE4_MACE, MT_JETFLAME, + // Boss 5 + MT_FANG, + MT_FBOMB, + MT_FSGNA, + MT_FSGNB, + // Black Eggman (Boss 7) MT_BLACKEGGMAN, MT_BLACKEGGMAN_HELPER, From 75701294eaeae79d9c859c2073a3113337738715 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 2 May 2019 18:11:44 +0100 Subject: [PATCH 02/38] Hardcode Fang waypoint object type (turns out no state is needed) --- src/dehacked.c | 1 + src/info.c | 27 +++++++++++++++++++++++++++ src/info.h | 1 + 3 files changed, 29 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 4aba5c495..cbb16e63e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6902,6 +6902,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FBOMB", "MT_FSGNA", "MT_FSGNB", + "MT_FANGWAYPOINT", // Black Eggman (Boss 7) "MT_BLACKEGGMAN", diff --git a/src/info.c b/src/info.c index e2f4c9246..fa24132a1 100644 --- a/src/info.c +++ b/src/info.c @@ -5453,6 +5453,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_FANGWAYPOINT + 294, // 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 + FRACUNIT, // radius + FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOTHINK, // flags + S_NULL // raisestate + }, + { // MT_BLACKEGGMAN 206, // doomednum S_BLACKEGG_STND, // spawnstate diff --git a/src/info.h b/src/info.h index 932c82573..8c8c2ccde 100644 --- a/src/info.h +++ b/src/info.h @@ -3836,6 +3836,7 @@ typedef enum mobj_type MT_FBOMB, MT_FSGNA, MT_FSGNB, + MT_FANGWAYPOINT, // Black Eggman (Boss 7) MT_BLACKEGGMAN, From 3bbc5d0b080f3f2f006cdcd489fd6b4a221007ff Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 2 May 2019 18:32:43 +0100 Subject: [PATCH 03/38] hardcoded A_DoNPCPain --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index cbb16e63e..0bbeaa4b2 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2225,6 +2225,7 @@ static actionpointer_t actionpointers[] = {{A_ParentTriesToSleep}, "A_PARENTTRIESTOSLEEP"}, {{A_CryingToMomma}, "A_CRYINGTOMOMMA"}, {{A_CheckFlags2}, "A_CHECKFLAGS2"}, + {{A_DoNPCPain}, "A_DONPCPAIN"}, {{NULL}, "NONE"}, diff --git a/src/info.h b/src/info.h index 8c8c2ccde..58eebb24e 100644 --- a/src/info.h +++ b/src/info.h @@ -239,6 +239,7 @@ void A_WhoCaresIfYourSonIsABee(); void A_ParentTriesToSleep(); void A_CryingToMomma(); void A_CheckFlags2(); +void A_DoNPCPain(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 diff --git a/src/p_enemy.c b/src/p_enemy.c index 9d2425e53..177d37e86 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -266,6 +266,7 @@ void A_WhoCaresIfYourSonIsABee(mobj_t *actor); void A_ParentTriesToSleep(mobj_t *actor); void A_CryingToMomma(mobj_t *actor); void A_CheckFlags2(mobj_t *actor); +void A_DoNPCPain(mobj_t *actor); //for p_enemy.c // @@ -11852,3 +11853,60 @@ void A_CheckFlags2(mobj_t *actor) if (actor->flags2 & locvar1) P_SetMobjState(actor, (statenum_t)locvar2); } + +// Function: A_DoNPCPain +// +// Description: Something that looks like a player was hit, put them in pain. +// +// var1 = If zero, always fling the same amount. +// Otherwise, slowly reduce the vertical +// and horizontal speed to the base value +// multiplied by this the more damage is done. +// var2 = If zero, use default fling values. +// Otherwise, vertical and horizontal speed +// will be multiplied by this. +// +void A_DoNPCPain(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t vspeed = 0; + fixed_t hspeed = FixedMul(4*FRACUNIT, actor->scale); +#ifdef HAVE_BLUA + if (LUA_CallAction("A_DoNPCPain", actor)) + return; +#endif + + actor->flags &= ~(MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT); + + var1 = var2 = 0; + A_Pain(actor); + + actor->z += P_MobjFlip(actor); + + if (actor->eflags & MFE_UNDERWATER) + vspeed = FixedDiv(10511*FRACUNIT,2600*FRACUNIT); + else + vspeed = FixedDiv(69*FRACUNIT,10*FRACUNIT); + + if (actor->target) + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x + actor->target->momx, actor->target->y + actor->target->momy); + + if (locvar1) + { + if (actor->info->spawnhealth) + return; // there's something very wrong here if you're using this action on something with no starting health + locvar1 += ((FRACUNIT - locvar1)/actor->info->spawnhealth)*actor->health; + hspeed = FixedMul(hspeed, locvar1); + vspeed = FixedMul(vspeed, locvar1); + } + + if (locvar2) + { + hspeed = FixedMul(hspeed, locvar2); + vspeed = FixedMul(vspeed, locvar2); + } + + P_SetObjectMomZ(actor, vspeed, false); + P_InstaThrust(actor, actor->angle, -hspeed); +} From fb17c1ac5ac9769015155b8ff1531360e528a363 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 2 May 2019 19:09:40 +0100 Subject: [PATCH 04/38] Hardcoded A_Boss5CheckOnGround --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 0bbeaa4b2..5cec3dfca 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2226,6 +2226,7 @@ static actionpointer_t actionpointers[] = {{A_CryingToMomma}, "A_CRYINGTOMOMMA"}, {{A_CheckFlags2}, "A_CHECKFLAGS2"}, {{A_DoNPCPain}, "A_DONPCPAIN"}, + {{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"}, {{NULL}, "NONE"}, diff --git a/src/info.h b/src/info.h index 58eebb24e..1a4446f80 100644 --- a/src/info.h +++ b/src/info.h @@ -240,6 +240,7 @@ void A_ParentTriesToSleep(); void A_CryingToMomma(); void A_CheckFlags2(); void A_DoNPCPain(); +void A_Boss5CheckOnGround(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 diff --git a/src/p_enemy.c b/src/p_enemy.c index 177d37e86..099f87bc1 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -267,6 +267,7 @@ void A_ParentTriesToSleep(mobj_t *actor); void A_CryingToMomma(mobj_t *actor); void A_CheckFlags2(mobj_t *actor); void A_DoNPCPain(mobj_t *actor); +void A_Boss5CheckOnGround(mobj_t *actor); //for p_enemy.c // @@ -11910,3 +11911,35 @@ void A_DoNPCPain(mobj_t *actor) P_SetObjectMomZ(actor, vspeed, false); P_InstaThrust(actor, actor->angle, -hspeed); } + +// Function: A_Boss5CheckOnGround +// +// Description: Ground checker. +// +// var1 = state to change to upon hitting ground. +// var2 = state to change to upon hitting ground if health == pinchhealth, assuming it exists +// +void A_Boss5CheckOnGround(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5CheckOnGround", actor)) + return; +#endif + + if ((!(actor->eflags & MFE_VERTICALFLIP) && actor->z <= actor->floorz) + || (actor->eflags & MFE_VERTICALFLIP && actor->z + actor->height >= actor->ceilingz)) + { + if (locvar2 && (!actor->health || (actor->health == actor->info->damage && !(actor->flags2 & MF2_STRONGBOX)))) + P_SetMobjState(actor, locvar2); + else + P_SetMobjState(actor, locvar1); + } + + if (actor->tracer && P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y) < 2*actor->radius) + { + actor->momx = (4*actor->momx)/5; + actor->momy = (4*actor->momy)/5; + } +} From 953a0c2967281f2fc106b78948c0a13d569be190 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 2 May 2019 21:21:15 +0100 Subject: [PATCH 05/38] Hardcoded A_Boss5ExtraRepeat --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 5cec3dfca..155e2b5ce 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2226,6 +2226,7 @@ static actionpointer_t actionpointers[] = {{A_CryingToMomma}, "A_CRYINGTOMOMMA"}, {{A_CheckFlags2}, "A_CHECKFLAGS2"}, {{A_DoNPCPain}, "A_DONPCPAIN"}, + {{A_Boss5ExtraRepeat}, "A_BOSS5EXTRAREPEAT"}, {{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"}, {{NULL}, "NONE"}, diff --git a/src/info.h b/src/info.h index 1a4446f80..f623aaa1f 100644 --- a/src/info.h +++ b/src/info.h @@ -240,6 +240,7 @@ void A_ParentTriesToSleep(); void A_CryingToMomma(); void A_CheckFlags2(); void A_DoNPCPain(); +void A_Boss5ExtraRepeat(); void A_Boss5CheckOnGround(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 diff --git a/src/p_enemy.c b/src/p_enemy.c index 099f87bc1..0746f629f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -11912,6 +11912,45 @@ void A_DoNPCPain(mobj_t *actor) P_InstaThrust(actor, actor->angle, -hspeed); } +// Function: A_Boss5PinchRepeat +// +// Description: Simple way to prepare A_Repeat. +// +// var1 = maximum value to setextravalue2 to (normally) +// var2 = pinch annoyance +// +void A_Boss5ExtraRepeat(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + INT32 calc; + INT32 locspawn; + INT32 lochealth; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5ExtraRepeat", actor)) + return; +#endif + + if (actor->extravalue2 > 0 && !(actor->flags2 & MF2_FRET)) + return; + + locspawn = actor->info->spawnhealth - actor->info->damage; + lochealth = actor->health - actor->info->damage; + + if (locspawn <= 0 || lochealth <= 0) + calc = locvar1; + else + calc = (locvar1*(locspawn - lochealth))/locspawn; + + if (calc > 2) + actor->extravalue2 = 1 + calc/2 + P_RandomKey(calc/2); + else + actor->extravalue2 = 1 + calc; + + if (lochealth <= 0) + actor->extravalue2 += locvar2; +} + // Function: A_Boss5CheckOnGround // // Description: Ground checker. From 61eb05eab2331267457d43481cbea3921652d5c9 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 2 May 2019 21:32:28 +0100 Subject: [PATCH 06/38] Hardcoded A_Boss5CheckFalling --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 155e2b5ce..baa5f13b3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2228,6 +2228,7 @@ static actionpointer_t actionpointers[] = {{A_DoNPCPain}, "A_DONPCPAIN"}, {{A_Boss5ExtraRepeat}, "A_BOSS5EXTRAREPEAT"}, {{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"}, + {{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"}, {{NULL}, "NONE"}, diff --git a/src/info.h b/src/info.h index f623aaa1f..166402651 100644 --- a/src/info.h +++ b/src/info.h @@ -242,6 +242,7 @@ void A_CheckFlags2(); void A_DoNPCPain(); void A_Boss5ExtraRepeat(); void A_Boss5CheckOnGround(); +void A_Boss5CheckFalling(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 diff --git a/src/p_enemy.c b/src/p_enemy.c index 0746f629f..118367da4 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -268,6 +268,7 @@ void A_CryingToMomma(mobj_t *actor); void A_CheckFlags2(mobj_t *actor); void A_DoNPCPain(mobj_t *actor); void A_Boss5CheckOnGround(mobj_t *actor); +void A_Boss5CheckFalling(mobj_t *actor); //for p_enemy.c // @@ -11982,3 +11983,31 @@ void A_Boss5CheckOnGround(mobj_t *actor) actor->momy = (4*actor->momy)/5; } } + +// Function: A_Boss5CheckFalling +// +// Description: Falling checker. +// +// var1 = state to change to when hitting ground. +// var2 = state to change to when falling. +// +void A_Boss5CheckFalling(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5CheckFalling", actor)) + return; +#endif + + if (actor->health && actor->extravalue2 > 1) + { + var1 = locvar1; + var2 = 0; + A_Boss5CheckOnGround(actor); + return; + } + + if (P_MobjFlip(actor)*actor->momz <= 0) + P_SetMobjState(actor, locvar2); +} From 266fa05e15be8f28f3a32ee8b59565fa57a05639 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 2 May 2019 21:34:00 +0100 Subject: [PATCH 07/38] fix a slipup in A_DoNPCPain I just noticed I made, whoops --- 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 118367da4..283a83559 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -11896,7 +11896,7 @@ void A_DoNPCPain(mobj_t *actor) if (locvar1) { - if (actor->info->spawnhealth) + if (!actor->info->spawnhealth) return; // there's something very wrong here if you're using this action on something with no starting health locvar1 += ((FRACUNIT - locvar1)/actor->info->spawnhealth)*actor->health; hspeed = FixedMul(hspeed, locvar1); From a0220454fdce8f78e89fc20a8e9330454950e94c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 3 May 2019 18:51:17 +0100 Subject: [PATCH 08/38] Hardcoded A_PrepareRepeat and A_Boss5Calm, added missing prototype for A_Boss5ExtraRepeat (and also fixed its description) --- src/dehacked.c | 2 ++ src/info.h | 2 ++ src/p_enemy.c | 41 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index baa5f13b3..9491aa6bc 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2226,7 +2226,9 @@ static actionpointer_t actionpointers[] = {{A_CryingToMomma}, "A_CRYINGTOMOMMA"}, {{A_CheckFlags2}, "A_CHECKFLAGS2"}, {{A_DoNPCPain}, "A_DONPCPAIN"}, + {{A_PrepareRepeat}, "A_PREPAREREPEAT"}, {{A_Boss5ExtraRepeat}, "A_BOSS5EXTRAREPEAT"}, + {{A_Boss5Calm}, "A_BOSS5CALM"}, {{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"}, {{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"}, diff --git a/src/info.h b/src/info.h index 166402651..7c93457d6 100644 --- a/src/info.h +++ b/src/info.h @@ -240,7 +240,9 @@ void A_ParentTriesToSleep(); void A_CryingToMomma(); void A_CheckFlags2(); void A_DoNPCPain(); +void A_PrepareRepeat(); void A_Boss5ExtraRepeat(); +void A_Boss5Calm(); void A_Boss5CheckOnGround(); void A_Boss5CheckFalling(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 283a83559..c7e1e90f3 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -267,6 +267,9 @@ void A_ParentTriesToSleep(mobj_t *actor); void A_CryingToMomma(mobj_t *actor); void A_CheckFlags2(mobj_t *actor); void A_DoNPCPain(mobj_t *actor); +void A_PrepareRepeat(mobj_t *actor); +void A_Boss5ExtraRepeat(mobj_t *actor); +void A_Boss5Calm(mobj_t *actor); void A_Boss5CheckOnGround(mobj_t *actor); void A_Boss5CheckFalling(mobj_t *actor); //for p_enemy.c @@ -11913,7 +11916,26 @@ void A_DoNPCPain(mobj_t *actor) P_InstaThrust(actor, actor->angle, -hspeed); } -// Function: A_Boss5PinchRepeat +// Function: A_PrepareRepeat +// +// Description: Simple way to prepare A_Repeat. +// +// var1 = value to set extravalue2 to +// var2 = unused +// +void A_PrepareRepeat(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_PrepareRepeat", actor)) + return; +#endif + + actor->extravalue2 = locvar1; +} + +// Function: A_Boss5ExtraRepeat // // Description: Simple way to prepare A_Repeat. // @@ -11952,6 +11974,23 @@ void A_Boss5ExtraRepeat(mobj_t *actor) actor->extravalue2 += locvar2; } +// Function: A_Boss5Calm +// +// Description: Simple way to disable MF2_FRET (and enable MF_SHOOTABLE the first time it's called) +// +// var1 = unused +// var2 = unused +// +void A_Boss5Calm(mobj_t *actor) +{ +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5Calm", actor)) + return; +#endif + actor->flags |= MF_SHOOTABLE; + actor->flags2 &= ~MF2_FRET; +} + // Function: A_Boss5CheckOnGround // // Description: Ground checker. From 6cd2b732731525c4c5db4ef06b3984fd4eef8abc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 3 May 2019 19:14:17 +0100 Subject: [PATCH 09/38] Hardcoded A_LookForBetter --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 9491aa6bc..6830d2c63 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2231,6 +2231,7 @@ static actionpointer_t actionpointers[] = {{A_Boss5Calm}, "A_BOSS5CALM"}, {{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"}, {{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"}, + {{A_LookForBetter}, "A_LOOKFORBETTER"}, {{NULL}, "NONE"}, diff --git a/src/info.h b/src/info.h index 7c93457d6..11d96de1c 100644 --- a/src/info.h +++ b/src/info.h @@ -245,6 +245,7 @@ void A_Boss5ExtraRepeat(); void A_Boss5Calm(); void A_Boss5CheckOnGround(); void A_Boss5CheckFalling(); +void A_LookForBetter(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 diff --git a/src/p_enemy.c b/src/p_enemy.c index c7e1e90f3..32f7d2aad 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -272,6 +272,7 @@ void A_Boss5ExtraRepeat(mobj_t *actor); void A_Boss5Calm(mobj_t *actor); void A_Boss5CheckOnGround(mobj_t *actor); void A_Boss5CheckFalling(mobj_t *actor); +void A_LookForBetter(mobj_t *actor); //for p_enemy.c // @@ -12050,3 +12051,29 @@ void A_Boss5CheckFalling(mobj_t *actor) if (P_MobjFlip(actor)*actor->momz <= 0) P_SetMobjState(actor, locvar2); } + +// Function: A_LookForBetter +// +// Description: A_Look, except it finds a better target in multiplayer, and doesn't lose the target in singleplayer. +// +// var1 lower 16 bits = 0 - looks only in front, 1 - looks all around +// var1 upper 16 bits = distance limit +// var2 = unused +// +void A_LookForBetter(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; + mobj_t *oldtarget = NULL; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_LookForBetter", actor)) + return; +#endif + + P_SetTarget(&oldtarget, actor->target); + + if (!P_LookForPlayers(actor, (locvar1 & 65535), false, FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale))) + P_SetTarget(&actor->target, oldtarget); + + A_FaceTarget(actor); +} From b4d8c2fa29183e8c6008b6a3463b1b781ef35ae4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 3 May 2019 19:46:41 +0100 Subject: [PATCH 10/38] Hardcoded A_Boss5PinchShot --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 6830d2c63..da806615d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2231,6 +2231,7 @@ static actionpointer_t actionpointers[] = {{A_Boss5Calm}, "A_BOSS5CALM"}, {{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"}, {{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"}, + {{A_Boss5PinchShot}, "A_BOSS5PINCHSHOT"}, {{A_LookForBetter}, "A_LOOKFORBETTER"}, {{NULL}, "NONE"}, diff --git a/src/info.h b/src/info.h index 11d96de1c..4db5d46b2 100644 --- a/src/info.h +++ b/src/info.h @@ -245,6 +245,7 @@ void A_Boss5ExtraRepeat(); void A_Boss5Calm(); void A_Boss5CheckOnGround(); void A_Boss5CheckFalling(); +void A_Boss5PinchShot(); void A_LookForBetter(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 diff --git a/src/p_enemy.c b/src/p_enemy.c index 32f7d2aad..2fac0fa39 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -272,6 +272,7 @@ void A_Boss5ExtraRepeat(mobj_t *actor); void A_Boss5Calm(mobj_t *actor); void A_Boss5CheckOnGround(mobj_t *actor); void A_Boss5CheckFalling(mobj_t *actor); +void A_Boss5PinchShot(mobj_t *actor); void A_LookForBetter(mobj_t *actor); //for p_enemy.c @@ -12052,6 +12053,42 @@ void A_Boss5CheckFalling(mobj_t *actor) P_SetMobjState(actor, locvar2); } +// Function: A_Boss5PinchShot +// +// Description: Fires a missile directly upwards if in pinch. +// +// var1 = object # to shoot +// var2 = height offset (from default of +48 FU) +// +void A_Boss5PinchShot(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t zoffset; + mobj_t *missile; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5PinchShot", actor)) + return; +#endif + + if (actor->health > actor->info->damage) + return; + + if (actor->eflags & MFE_VERTICALFLIP) + zoffset = actor->z + actor->height - FixedMul((48 + locvar2)*FRACUNIT, actor->scale); + else + zoffset = actor->z + FixedMul((48 + locvar2)*FRACUNIT, actor->scale); + + missile = P_SpawnPointMissile(actor, actor->x, actor->y, zoffset, locvar1, + actor->x, actor->y, zoffset); + + if (!missile) + return; + + missile->momx = missile->momy = 0; + missile->momz = P_MobjFlip(actor)*missile->info->speed/2; +} + // Function: A_LookForBetter // // Description: A_Look, except it finds a better target in multiplayer, and doesn't lose the target in singleplayer. From b03bfbabe4c7efdb508032c96905a278f985237a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 3 May 2019 20:00:31 +0100 Subject: [PATCH 11/38] Hardcode A_DoNPCSkid --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index da806615d..e824b0652 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2225,6 +2225,7 @@ static actionpointer_t actionpointers[] = {{A_ParentTriesToSleep}, "A_PARENTTRIESTOSLEEP"}, {{A_CryingToMomma}, "A_CRYINGTOMOMMA"}, {{A_CheckFlags2}, "A_CHECKFLAGS2"}, + {{A_DoNPCSkid}, "A_DONPCSKID"}, {{A_DoNPCPain}, "A_DONPCPAIN"}, {{A_PrepareRepeat}, "A_PREPAREREPEAT"}, {{A_Boss5ExtraRepeat}, "A_BOSS5EXTRAREPEAT"}, diff --git a/src/info.h b/src/info.h index 4db5d46b2..cb98e6962 100644 --- a/src/info.h +++ b/src/info.h @@ -239,6 +239,7 @@ void A_WhoCaresIfYourSonIsABee(); void A_ParentTriesToSleep(); void A_CryingToMomma(); void A_CheckFlags2(); +void A_DoNPCSkid(); void A_DoNPCPain(); void A_PrepareRepeat(); void A_Boss5ExtraRepeat(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 2fac0fa39..469730483 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -266,6 +266,7 @@ void A_WhoCaresIfYourSonIsABee(mobj_t *actor); void A_ParentTriesToSleep(mobj_t *actor); void A_CryingToMomma(mobj_t *actor); void A_CheckFlags2(mobj_t *actor); +void A_DoNPCSkid(mobj_t *actor); void A_DoNPCPain(mobj_t *actor); void A_PrepareRepeat(mobj_t *actor); void A_Boss5ExtraRepeat(mobj_t *actor); @@ -11861,6 +11862,57 @@ void A_CheckFlags2(mobj_t *actor) P_SetMobjState(actor, (statenum_t)locvar2); } +// Function: A_DoNPCSkid +// +// Description: Something that looks like a player is skidding. +// +// var1 = state to change to upon being slow enough +// var2 = minimum speed +// +void A_DoNPCSkid(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t x, y, z; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_DoNPCSkid", actor)) + return; +#endif + + x = actor->x; + y = actor->y; + z = actor->y; + + if (!locvar2) + locvar2 = FRACUNIT/2; + + if ((FixedHypot(actor->momx, actor->momy) < locvar2) + || !P_TryMove(actor, actor->x + actor->momx, actor->y + actor->momy, false)) + { + actor->momx = actor->momy = 0; + P_SetMobjState(actor, locvar1); + return; + } + else + { + actor->momx = (2*actor->momx)/3; + actor->momy = (2*actor->momy)/3; + } + + P_TeleportMove(actor, x, y, z); + + // Spawn a particle every 3 tics. + if (!(leveltime % 3)) + { + mobj_t *particle = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_SPINDUST); + particle->tics = 10; + + P_SetScale(particle, 2*actor->scale/3); + particle->destscale = actor->scale; + P_SetObjectMomZ(particle, FRACUNIT, false); + } +} + // Function: A_DoNPCPain // // Description: Something that looks like a player was hit, put them in pain. From 0d7cd34882ace8dd254986b75993fd39139c60cd Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 3 May 2019 20:52:56 +0100 Subject: [PATCH 12/38] Hardcoded A_Boss5MakeItRain --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index e824b0652..946e6f117 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2233,6 +2233,7 @@ static actionpointer_t actionpointers[] = {{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"}, {{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"}, {{A_Boss5PinchShot}, "A_BOSS5PINCHSHOT"}, + {{A_Boss5MakeItRain}, "A_BOSS5MAKEITRAIN"}, {{A_LookForBetter}, "A_LOOKFORBETTER"}, {{NULL}, "NONE"}, diff --git a/src/info.h b/src/info.h index cb98e6962..948ecef97 100644 --- a/src/info.h +++ b/src/info.h @@ -247,6 +247,7 @@ void A_Boss5Calm(); void A_Boss5CheckOnGround(); void A_Boss5CheckFalling(); void A_Boss5PinchShot(); +void A_Boss5MakeItRain(); void A_LookForBetter(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 diff --git a/src/p_enemy.c b/src/p_enemy.c index 469730483..10662ba88 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -274,6 +274,7 @@ void A_Boss5Calm(mobj_t *actor); void A_Boss5CheckOnGround(mobj_t *actor); void A_Boss5CheckFalling(mobj_t *actor); void A_Boss5PinchShot(mobj_t *actor); +void A_Boss5MakeItRain(mobj_t *actor); void A_LookForBetter(mobj_t *actor); //for p_enemy.c @@ -12141,6 +12142,42 @@ void A_Boss5PinchShot(mobj_t *actor) missile->momz = P_MobjFlip(actor)*missile->info->speed/2; } +// Function: A_Boss5MakeItRain +// +// Description: Pinch crisis. +// +// var1 = object # to shoot +// var2 = height offset (from default of +48 FU) +// +void A_Boss5MakeItRain(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + INT32 offset = (48 + locvar2)<<16; // upper 16 bits, not fixed_t! + INT32 i; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5MakeItRain", actor)) + return; +#endif + + actor->flags2 |= MF2_STRONGBOX; + + var1 = locvar1; + var2 = offset + 90; + A_TrapShot(actor); + + for (i = 0; i < 8; i++) + { + actor->angle += ANGLE_45; + + var1 = locvar1; + var2 = offset + (i & 1) ? 55 : 70; + A_TrapShot(actor); + } + + actor->extravalue2 = 0; +} + // Function: A_LookForBetter // // Description: A_Look, except it finds a better target in multiplayer, and doesn't lose the target in singleplayer. From df99e9328893f021e65c6764afb5039478a806f7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 3 May 2019 22:58:54 +0100 Subject: [PATCH 13/38] Hardcoded A_Boss5FindWaypoint ...that took a while x_x --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 946e6f117..dbe0491ef 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2225,6 +2225,7 @@ static actionpointer_t actionpointers[] = {{A_ParentTriesToSleep}, "A_PARENTTRIESTOSLEEP"}, {{A_CryingToMomma}, "A_CRYINGTOMOMMA"}, {{A_CheckFlags2}, "A_CHECKFLAGS2"}, + {{A_Boss5FindWaypoint}, "A_BOSS5FINDWAYPOINT"}, {{A_DoNPCSkid}, "A_DONPCSKID"}, {{A_DoNPCPain}, "A_DONPCPAIN"}, {{A_PrepareRepeat}, "A_PREPAREREPEAT"}, diff --git a/src/info.h b/src/info.h index 948ecef97..f052972e6 100644 --- a/src/info.h +++ b/src/info.h @@ -239,6 +239,7 @@ void A_WhoCaresIfYourSonIsABee(); void A_ParentTriesToSleep(); void A_CryingToMomma(); void A_CheckFlags2(); +void A_Boss5FindWaypoint(); void A_DoNPCSkid(); void A_DoNPCPain(); void A_PrepareRepeat(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 10662ba88..227b8dd47 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -266,6 +266,7 @@ void A_WhoCaresIfYourSonIsABee(mobj_t *actor); void A_ParentTriesToSleep(mobj_t *actor); void A_CryingToMomma(mobj_t *actor); void A_CheckFlags2(mobj_t *actor); +void A_Boss5FindWaypoint(mobj_t *actor); void A_DoNPCSkid(mobj_t *actor); void A_DoNPCPain(mobj_t *actor); void A_PrepareRepeat(mobj_t *actor); @@ -11863,6 +11864,193 @@ void A_CheckFlags2(mobj_t *actor) P_SetMobjState(actor, (statenum_t)locvar2); } +// Function: A_Boss5FindWaypoint +// +// Description: Finds the next waypoint in sequence and sets it as its tracer. +// +// var1 = if 1, always go to ambush-marked waypoint. if 2, go to MT_BOSSFLYPOINT. +// var2 = unused +// +void A_Boss5FindWaypoint(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; + boolean avoidcenter; + INT32 i; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5FindWaypoint", actor)) + return; +#endif + + avoidcenter = !actor->tracer || (mobj->health == mobj->info->damage+1); + + if (locvar1 == 2) // look for the boss waypoint + { + for (i = 0; i < nummapthings; i++) + { + if (!mapthings[i].mobj) + continue; + if (mapthings[i].mobj->type != MT_BOSSFLYPOINT) + continue; + P_SetTarget(&actor->tracer, mapthings[i].mobj); + break; + } + if (i == nummapthings) + return; // no boss flypoints found + } + else if (locvar1 == 1) // always go to ambush-marked waypoint + { + if (avoidcenter) + goto nowaypoints; // if we can't go the center, why on earth are we doing this? + + for (i = 0; i < nummapthings; i++) + { + if (!mapthings[i].mobj) + continue; + if (mapthings[i].mobj->type != MT_FANGWAYPOINT) + continue; + if (mapthings[i].options & MTF_AMBUSH) + { + P_SetTarget(&actor->tracer, mapthings[i].mobj); + break; + } + } + + if (i == nummapthings) + goto nowaypoints; + } + else // locvar1 == 0 + { + fixed_t hackoffset = P_MobjFlip(actor)*56*FRACUNIT; + INT32 numwaypoints = 0; + mobj_t **waypoints; + INT32 key; + + actor->z += hackoffset; + + // first, count how many waypoints we have + for (i = 0; i < nummapthings; i++) + { + if (!mapthings[i].mobj) + continue; + if (mapthings[i].mobj->type != MT_FANGWAYPOINT) + continue; + if (actor->tracer == mapthings[i].mobj) // this was your tracer last time + continue; + if (mapthings[i].options & MTF_AMBUSH) + { + if (avoidcenter) + continue; + } + else if (mapthings[i].mobj->reactiontime > 0) + continue; + numwaypoints++; + } + + // players also count as waypoints apparently + if (actor->extravalue2 > 1) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (!players[i].mo) + continue; + if (players[i].spectator) + continue; + if (players[i].mo->health <= 0) + continue; + if (players[i].powers[pw_flashing]) + continue; + if (actor->tracer == players[i].mo) // this was your tracer last time + continue; + if (!P_CheckSight(actor, players[i].mo)) + continue; + numwaypoints++; + } + } + + if (!numwaypoints) + { + // restore z position + actor->z -= hackoffset; + goto nowaypoints; // no waypoints :( + } + + // allocate the table and reset count to zero + waypoints = Z_Calloc(sizeof(*waypoints)*numwaypoints, PU_STATIC, NULL); + numwaypoints = 0; + + // now find them again and add them to the table! + for (i = 0; i < nummapthings; i++) + { + if (!mapthings[i].mobj) + continue; + if (mapthings[i].mobj->type != MT_FANGWAYPOINT) + continue; + if (actor->tracer == mapthings[i].mobj) // this was your tracer last time + continue; + if (mapthings[i].options & MTF_AMBUSH) + { + if (avoidcenter) + continue; + waypoints[numwaypoints++] = mapthings[i].mobj; + } + else if (mapthings[i].mobj->reactiontime > 0) + mapthings[i].mobj->reactiontime--; + else + waypoints[numwaypoints++] = mapthings[i].mobj; + } + + if (actor->extravalue2 > 1) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (!players[i].mo) + continue; + if (players[i].spectator) + continue; + if (players[i].mo->health <= 0) + continue; + if (players[i].powers[pw_flashing]) + continue; + if (actor->tracer == players[i].mo) // this was your tracer last time + continue; + if (!P_CheckSight(actor, players[i].mo)) + continue; + waypoints[numwaypoints++] = players[i].mo; + } + } + + // restore z position + actor->z -= hackoffset; + + if (!numwaypoints) + goto nowaypoints; // ??? + + key = P_RandomKey(numwaypoints); + + P_SetTarget(&actor->tracer, waypoints[key]); + if (actor->tracer->type == MT_FANGWAYPOINT) + actor->tracer->reactiontime = numwaypoints/4; // Monster Iestyn: is this how it should be? I count center waypoints as waypoints unlike the original Lua script + Z_Free(waypoints); // free table + } + + // now face the tracer you just set! + A_FaceTracer(actor); + return; + +nowaypoints: + // no waypoints at all, guess the mobj has to disappear + if (actor->health) + P_KillMobj(actor, NULL, NULL, 0); + else + P_RemoveMobj(actor); + return; +} + // Function: A_DoNPCSkid // // Description: Something that looks like a player is skidding. From ee1fd72f9fe4a12d84919d4bc2083e0bf59ed227 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 3 May 2019 23:12:03 +0100 Subject: [PATCH 14/38] ah, forgot to do this --- src/p_enemy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 227b8dd47..3b90f65a9 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -12028,7 +12028,10 @@ void A_Boss5FindWaypoint(mobj_t *actor) actor->z -= hackoffset; if (!numwaypoints) + { + Z_Free(waypoints); // free table goto nowaypoints; // ??? + } key = P_RandomKey(numwaypoints); From 54fea4d0b92ef5d61abccb79b49c2f70454fa5c1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 3 May 2019 23:16:11 +0100 Subject: [PATCH 15/38] AND I forgot these checks, confound it --- src/p_enemy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 3b90f65a9..85786eeec 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -11944,6 +11944,8 @@ void A_Boss5FindWaypoint(mobj_t *actor) } else if (mapthings[i].mobj->reactiontime > 0) continue; + if (!P_CheckSight(actor, mapthings[i].mobj)) + continue; numwaypoints++; } @@ -11998,7 +12000,7 @@ void A_Boss5FindWaypoint(mobj_t *actor) } else if (mapthings[i].mobj->reactiontime > 0) mapthings[i].mobj->reactiontime--; - else + else if (P_CheckSight(actor, mapthings[i].mobj)) waypoints[numwaypoints++] = mapthings[i].mobj; } From a5331f8024dc57d38a2ebdd6746d6060f06ef468 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 4 May 2019 17:15:59 +0100 Subject: [PATCH 16/38] Fix A_LookForBetter to not leave a stray thinker reference lingering potentially forever, as toaster pointed out it might do. --- 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 85786eeec..d9f8af96f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -12389,10 +12389,10 @@ void A_LookForBetter(mobj_t *actor) return; #endif - P_SetTarget(&oldtarget, actor->target); + oldtarget = actor->target; if (!P_LookForPlayers(actor, (locvar1 & 65535), false, FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale))) - P_SetTarget(&actor->target, oldtarget); + actor->target = oldtarget; A_FaceTarget(actor); } From b205602db6be8ab32438509bd7bd148ca70cde85 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 4 May 2019 19:43:14 +0100 Subject: [PATCH 17/38] DO NOT USE FRACUNIT AS A LAZY WAY TO DO UPPER 16 BITS FOR ACTION VARS --- src/info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index fa24132a1..28ca6452d 100644 --- a/src/info.c +++ b/src/info.c @@ -1364,7 +1364,7 @@ state_t states[NUMSTATES] = {SPR_FANG, 5, 0, {A_Repeat}, 3, S_FANG_FIRE1, S_FANG_WAIT1}, // S_FANG_FIREREPEAT // End of loop {SPR_FANG, 19, 18, {A_LookForBetter}, 1, 0, S_FANG_LOBSHOT2}, // S_FANG_LOBSHOT1 - {SPR_FANG, 20, 18, {A_BrakLobShot}, MT_FBOMB, 32+FRACUNIT, S_FANG_WAIT1}, // S_FANG_LOBSHOT2 + {SPR_FANG, 20, 18, {A_BrakLobShot}, MT_FBOMB, 32+(1<<16), S_FANG_WAIT1}, // S_FANG_LOBSHOT2 {SPR_FANG, FF_ANIMATE|15, 70, {NULL}, 1, 5, S_FANG_WAIT2}, // S_FANG_WAIT1 {SPR_FANG, 0, 35, {A_Look}, 1, 0, S_FANG_IDLE1}, // S_FANG_WAIT2 @@ -1394,7 +1394,7 @@ state_t states[NUMSTATES] = {SPR_FANG, 17, 104, {NULL}, 0, 0, S_FANG_DIE5}, // S_FANG_DIE4 {SPR_FANG, 11, 0, {A_PlaySound}, sfx_jump, 0, S_FANG_DIE6}, // S_FANG_DIE5 - {SPR_FANG, 11, 1, {A_ZThrust}, 6, FRACUNIT|1, S_FANG_DIE7}, // S_FANG_DIE6 + {SPR_FANG, 11, 1, {A_ZThrust}, 6, (1<<16)|1, S_FANG_DIE7}, // S_FANG_DIE6 {SPR_FANG, 11, 1, {A_Boss5CheckFalling}, S_FANG_FLEEPATHING1, S_FANG_DIE8, S_FANG_DIE7}, // S_FANG_DIE7 {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_FLEEPATHING1, 0, S_FANG_DIE8}, // S_FANG_DIE8 From 445709037daab969df682e6cb9ab2f1c0bc31f97 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 4 May 2019 20:17:00 +0100 Subject: [PATCH 18/38] Fix some compiler complaints about A_Boss5FindWaypoint --- src/p_enemy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index d9f8af96f..e3573e604 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -15,6 +15,7 @@ #include "doomdef.h" #include "g_game.h" #include "p_local.h" +#include "p_setup.h" #include "r_main.h" #include "r_state.h" #include "s_sound.h" @@ -22,6 +23,7 @@ #include "m_misc.h" #include "r_things.h" #include "i_video.h" +#include "z_zone.h" #include "lua_hook.h" #ifdef HW3SOUND @@ -11876,13 +11878,13 @@ void A_Boss5FindWaypoint(mobj_t *actor) INT32 locvar1 = var1; //INT32 locvar2 = var2; boolean avoidcenter; - INT32 i; + UINT32 i; #ifdef HAVE_BLUA if (LUA_CallAction("A_Boss5FindWaypoint", actor)) return; #endif - avoidcenter = !actor->tracer || (mobj->health == mobj->info->damage+1); + avoidcenter = !actor->tracer || (actor->health == actor->info->damage+1); if (locvar1 == 2) // look for the boss waypoint { From 7b6b34212b6073cc241c9d4fd1a3cab687f50490 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 4 May 2019 20:20:34 +0100 Subject: [PATCH 19/38] Swap "S_TNTBARREL_EXPL1" for S_NULL as a temporary measure until I actually hardcode the explosion states. As of now, you can now compile this branch with no issues. But Fang won't work properly for a while yet, we'll get there don't worry. --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 28ca6452d..851e565c9 100644 --- a/src/info.c +++ b/src/info.c @@ -5385,7 +5385,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_TNTBARREL_EXPL1, // deathstate + S_NULL, //S_TNTBARREL_EXPL1, // deathstate S_NULL, // xdeathstate sfx_s3k4e, // deathsound 20*FRACUNIT, // speed From 691ae982e741ef0a3d70959bc088d1a8ff2e7337 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 4 May 2019 21:31:46 +0100 Subject: [PATCH 20/38] S_FANG_SLIDE wasn't defined in the Lua script, despite being declared :| Also Fang seems to turn invisible after his first jump for some reason, and I can't figure out why??? --- src/dehacked.c | 1 - src/info.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index dbe0491ef..dc30f7c7a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4561,7 +4561,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FANG_BOUNCE4", "S_FANG_FALL1", "S_FANG_FALL2", - "S_FANG_SLIDE", "S_FANG_CHECKPATH1", "S_FANG_CHECKPATH2", "S_FANG_PATHINGCONT1", diff --git a/src/info.h b/src/info.h index f052972e6..6d115d564 100644 --- a/src/info.h +++ b/src/info.h @@ -1475,7 +1475,6 @@ typedef enum state S_FANG_BOUNCE4, S_FANG_FALL1, S_FANG_FALL2, - S_FANG_SLIDE, S_FANG_CHECKPATH1, S_FANG_CHECKPATH2, S_FANG_PATHINGCONT1, From d44265a217c1411abc6ba13e68447497e143b213 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 4 May 2019 22:38:14 +0100 Subject: [PATCH 21/38] Mystery solved, he was turning "invisible" because of this mistake in A_DoNPCSkid --- 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 e3573e604..807ec93a9 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -12077,7 +12077,7 @@ void A_DoNPCSkid(mobj_t *actor) x = actor->x; y = actor->y; - z = actor->y; + z = actor->z; if (!locvar2) locvar2 = FRACUNIT/2; From 09368963dd2c9f425c32cce65f9a97a4bba741fb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 4 May 2019 22:46:27 +0100 Subject: [PATCH 22/38] hardcode MT_FBOMB's MobjSpawn hook function --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5457c4f68..2b16d7cc7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9100,6 +9100,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_NIGHTSSTAR: if (nummaprings >= 0) nummaprings++; + break; + case MT_FBOMB: + mobj->flags2 |= MF2_EXPLOSION; + break; default: break; } From 9e26d7bdaa721ed292a4ed413f85caa2bb96d519 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 14:09:09 +0100 Subject: [PATCH 23/38] I just checked how P_LookForPlayers works, and it turns out it doesn't modify the target *unless* it returns true. So I guess we've no need to account for a change in target in A_LookForBetter after all? --- src/p_enemy.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 807ec93a9..b3039b74e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -12385,16 +12385,11 @@ void A_LookForBetter(mobj_t *actor) { INT32 locvar1 = var1; //INT32 locvar2 = var2; - mobj_t *oldtarget = NULL; #ifdef HAVE_BLUA if (LUA_CallAction("A_LookForBetter", actor)) return; #endif - oldtarget = actor->target; - - if (!P_LookForPlayers(actor, (locvar1 & 65535), false, FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale))) - actor->target = oldtarget; - + P_LookForPlayers(actor, (locvar1 & 65535), false, FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale)); A_FaceTarget(actor); } From 289a4123772957bdd8fcaddf8de26e95d3f2ae89 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 15:34:06 +0100 Subject: [PATCH 24/38] Hardcode the boss thinker function --- src/p_mobj.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2b16d7cc7..a7623e4d9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5013,6 +5013,47 @@ static void P_Boss4Thinker(mobj_t *mobj) A_FaceTarget(mobj); } +// +// AI for the fifth boss. +// +static void P_Boss5Thinker(mobj_t *mobj) +{ + if (!mobj->health) + { + if (mobj->state == &states[mobj->info->xdeathstate]) + mobj->momz -= (2*FRACUNIT)/3; + else if (mobj->tracer && P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y) < 2*mobj->radius) + mobj->flags &= ~MF_NOCLIP; + } + else + { + if (mobj->flags2 & MF2_FRET && (leveltime & 1) + && mobj->state != &states[S_FANG_PAIN1] && mobj->state != &states[S_FANG_PAIN2]) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + } + + if (mobj->state == &states[S_FANG_BOUNCE3] + || mobj->state == &states[S_FANG_BOUNCE4] + || mobj->state == &states[S_FANG_PINCHBOUNCE3] + || mobj->state == &states[S_FANG_PINCHBOUNCE4]) + { + if (P_MobjFlip(mobj)*mobj->momz > 0 + && abs(mobj->momx) < FRACUNIT/2 && abs(mobj->momy) < FRACUNIT/2 + && !P_IsObjectOnGround(mobj)) + { + mobj_t *prevtarget = mobj->target; + P_SetTarget(&mobj->target, NULL); + var1 = var2 = 0; + A_DoNPCPain(mobj); + P_SetTarget(&mobj->target, prevtarget); + P_SetMobjState(mobj, S_FANG_WALLHIT); + mobj->extravalue2++; + } + } +} + // // AI for Black Eggman // Note: You CANNOT have more than ONE Black Eggman @@ -7378,6 +7419,9 @@ void P_MobjThinker(mobj_t *mobj) case MT_EGGMOBILE4: P_Boss4Thinker(mobj); break; + case MT_FANG: + P_Boss5Thinker(mobj); + break; case MT_BLACKEGGMAN: P_Boss7Thinker(mobj); break; From 9c0c0ad3dcdb856c37e549fb99b0f5d051f4209b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 16:03:34 +0100 Subject: [PATCH 25/38] hardcoded the boss's A_BossDeath behaviour. (also turned this part of the function into a switch case to make things neater) --- src/p_enemy.c | 132 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 44 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index b3039b74e..c983a0dc3 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3562,59 +3562,103 @@ bossjustdie: else if (P_MobjWasRemoved(mo)) return; #endif - if (mo->type == MT_BLACKEGGMAN || mo->type == MT_CYBRAKDEMON) + switch (mo->type) { - mo->flags |= MF_NOCLIP; - mo->flags &= ~MF_SPECIAL; + case MT_BLACKEGGMAN: + case MT_CYBRAKDEMON: + { + mo->flags |= MF_NOCLIP; + mo->flags &= ~MF_SPECIAL; - S_StartSound(NULL, sfx_befall); - } - else if (mo->type == MT_KOOPA) - { - junk.tag = 650; - EV_DoCeiling(&junk, raiseToHighest); - return; - } - else // eggmobiles - { - // Stop exploding and prepare to run. - P_SetMobjState(mo, mo->info->xdeathstate); - if (P_MobjWasRemoved(mo)) + S_StartSound(NULL, sfx_befall); + break; + } + case MT_KOOPA: + { + junk.tag = 650; + EV_DoCeiling(&junk, raiseToHighest); return; - - P_SetTarget(&mo->target, NULL); - - // Flee! Flee! Find a point to escape to! If none, just shoot upward! - // scan the thinkers to find the runaway point - for (th = thinkercap.next; th != &thinkercap; th = th->next) + } + case MT_FANG: { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - - mo2 = (mobj_t *)th; - - if (mo2->type == MT_BOSSFLYPOINT) + if (mo->tracer) { - // If this one's closer then the last one, go for it. - if (!mo->target || - P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) < - P_AproxDistance(P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y), mo->z - mo->target->z)) - P_SetTarget(&mo->target, mo2); - // Otherwise... Don't! + var1 = var2 = 0; + A_Boss5Jump(mo); + mo->momx = ((16 - 1)*mo->momx)/16; + mo->momy = ((16 - 1)*mo->momy)/16; + if (!(mo->flags2 & MF2_AMBUSH)) + { + const fixed_t time = FixedHypot(mo->tracer->x - mo->x, mo->tracer->y - mo->y)/FixedHypot(mo->momx, mo->momy); + const fixed_t speed = 64*FRACUNIT; + mobj_t *pole = P_SpawnMobj( + mo->tracer->x - P_ReturnThrustX(mo->tracer, mo->tracer->angle, speed*time), + mo->tracer->y - P_ReturnThrustY(mo->tracer, mo->tracer->angle, speed*time), + mo->tracer->floorz + 4*FRACUNIT, + MT_FSGNB); + P_SetTarget(&pole->tracer, P_SpawnMobj( + pole->x + P_ReturnThrustX(pole, mo->tracer->angle, FRACUNIT), + pole->y + P_ReturnThrustY(pole, mo->tracer->angle, FRACUNIT), + pole->z + 256*FRACUNIT, + MT_FSGNA)); + pole->angle = mo->tracer->angle; + pole->tracer->angle = pole->angle - ANGLE_90; + pole->momx = P_ReturnThrustX(pole, pole->angle, speed); + pole->momy = P_ReturnThrustY(pole, pole->angle, speed); + pole->tracer->momx = pole->momx; + pole->tracer->momy = pole->momy; + } } + else + { + P_SetObjectMomZ(mo, 10*FRACUNIT, false); + mo->flags |= MF_NOGRAVITY; + } + mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; + return; } - - mo->flags |= MF_NOGRAVITY|MF_NOCLIP; - mo->flags |= MF_NOCLIPHEIGHT; - - if (mo->target) + default: //eggmobiles { - mo->angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y); - mo->flags2 |= MF2_BOSSFLEE; - mo->momz = FixedMul(FixedDiv(mo->target->z - mo->z, P_AproxDistance(mo->x-mo->target->x,mo->y-mo->target->y)), FixedMul(2*FRACUNIT, mo->scale)); + // Stop exploding and prepare to run. + P_SetMobjState(mo, mo->info->xdeathstate); + if (P_MobjWasRemoved(mo)) + return; + + P_SetTarget(&mo->target, NULL); + + // Flee! Flee! Find a point to escape to! If none, just shoot upward! + // scan the thinkers to find the runaway point + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type == MT_BOSSFLYPOINT) + { + // If this one's closer then the last one, go for it. + if (!mo->target || + P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) < + P_AproxDistance(P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y), mo->z - mo->target->z)) + P_SetTarget(&mo->target, mo2); + // Otherwise... Don't! + } + } + + mo->flags |= MF_NOGRAVITY|MF_NOCLIP; + mo->flags |= MF_NOCLIPHEIGHT; + + if (mo->target) + { + mo->angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y); + mo->flags2 |= MF2_BOSSFLEE; + mo->momz = FixedMul(FixedDiv(mo->target->z - mo->z, P_AproxDistance(mo->x-mo->target->x,mo->y-mo->target->y)), FixedMul(2*FRACUNIT, mo->scale)); + } + else + mo->momz = FixedMul(2*FRACUNIT, mo->scale); + break; } - else - mo->momz = FixedMul(2*FRACUNIT, mo->scale); } if (mo->type == MT_EGGMOBILE2) From f7fbf404376dc3cb91999aebab5d566bd90d0a62 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 16:42:50 +0100 Subject: [PATCH 26/38] Hardcoded MT_FSGNA's MobjThinker hook function --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index a7623e4d9..bc43fbe1e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7330,6 +7330,10 @@ void P_MobjThinker(mobj_t *mobj) mobj->angle += (angle_t)mobj->movecount; } break; + case MT_FSGNA: + if (mobj->movedir) + mobj->angle += mobj->movedir; + break; default: if (mobj->fuse) { // Scenery object fuse! Very basic! From 373d12cb82e26fe70657dc9821146f1486df893e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 17:36:55 +0100 Subject: [PATCH 27/38] Hardcode "slapstick" --- src/p_map.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index ceaa6ca24..ffe6cf916 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -551,6 +551,44 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) } } +// Boss 5 post-defeat comedy +static void P_SlapStick(mobj_t *fang, mobj_t *pole) +{ + fixed_t momx1, momx2, momy1, momy2; + +#define dist 3 + momx1 = pole->momx/dist; + momy1 = pole->momy/dist; + momx2 = fang->momx/dist; + momy2 = fang->momy/dist; + + pole->tracer->momx = momx1 + (dist-1)*momx2; + pole->tracer->momy = momy1 + (dist-1)*momy2; + fang->momx = (dist-1)*momx1 + momx2; + fang->momy = (dist-1)*momy1 + momy2; +#undef dist + + P_SetMobjState(pole, pole->info->deathstate); + + P_SetObjectMomZ(pole->tracer, 6*FRACUNIT, false); + pole->tracer->flags &= ~(MF_NOGRAVITY|MF_NOCLIP); + pole->tracer->movedir = ANGLE_67h; + if ((R_PointToAngle(fang->x - pole->tracer->x, fang->y - pole->tracer->y) - pole->angle) > ANGLE_180) + pole->tracer->movedir = InvAngle(pole->tracer->movedir); + + P_SetObjectMomZ(fang, 14*FRACUNIT, false); + fang->flags |= MF_NOGRAVITY|MF_NOCLIP; + P_SetMobjState(fang, fang->info->xdeathstate); + + pole->tracer->tics = pole->tics = fang->tics; + + var1 = var2 = 0; + A_Scream(pole->tracer); + S_StartSound(fang, sfx_altdi1); + + P_SetTarget(&pole->tracer, NULL); +} + // // PIT_CheckThing // @@ -780,6 +818,20 @@ static boolean PIT_CheckThing(mobj_t *thing) } #endif + if (tmthing->type == MT_FANG && thing->type == MT_FSGNB) + { + if (thing->z > tmthing->z + tmthing->height) + return true; // overhead + if (thing->z + thing->height < tmthing->z) + return true; // underneath + if (!thing->tracer) + return true; + P_SlapStick(tmthing, thing); + // no return value was used in the original prototype script at this point, + // so I'm assuming we fall back on the solid code to determine how it all ends? + // -- Monster Iestyn + } + // Billiards mines! if (thing->type == MT_BIGMINE) { From b0087616c73bfe7c7866ad427e7d39dbcb43288c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 18:22:19 +0100 Subject: [PATCH 28/38] Hardcoded the boss's TouchSpecial hook. Also cleaned up this part of P_TouchSpecialThing a bit while I'm here --- src/p_inter.c | 106 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 34 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 177b8d16e..70050a4cd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -375,44 +375,82 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) /////ENEMIES & BOSSES!!///////////////////////////////// //////////////////////////////////////////////////////// - if (special->type == MT_BLACKEGGMAN) + switch (special->type) { - P_DamageMobj(toucher, special, special, 1, 0); // ouch - return; - } - - if (special->type == MT_BIGMINE) - { - special->momx = toucher->momx/3; - special->momy = toucher->momy/3; - special->momz = toucher->momz/3; - toucher->momx /= -8; - toucher->momy /= -8; - toucher->momz /= -8; - special->flags &= ~MF_SPECIAL; - if (special->info->activesound) - S_StartSound(special, special->info->activesound); - P_SetTarget(&special->tracer, toucher); - player->homing = 0; - return; - } - - if (special->type == MT_GSNAPPER && !elementalpierce - && toucher->z < special->z + special->height && toucher->z + toucher->height > special->z - && P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) - return; // Can only hit snapper from above - - if (special->type == MT_SPINCUSHION - && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0)) - { - if (player->pflags & PF_BOUNCING) + case MT_BLACKEGGMAN: { - toucher->momz = -toucher->momz; - P_DoAbilityBounce(player, false); + P_DamageMobj(toucher, special, special, 1, 0); // ouch return; } - else if (P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) - return; // Cannot hit sharp from above + case MT_BIGMINE: + { + special->momx = toucher->momx/3; + special->momy = toucher->momy/3; + special->momz = toucher->momz/3; + toucher->momx /= -8; + toucher->momy /= -8; + toucher->momz /= -8; + special->flags &= ~MF_SPECIAL; + if (special->info->activesound) + S_StartSound(special, special->info->activesound); + P_SetTarget(&special->tracer, toucher); + player->homing = 0; + return; + } + case MT_GSNAPPER: + if (!elementalpierce + && toucher->z < special->z + special->height + && toucher->z + toucher->height > special->z + && P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) + return; // Can only hit snapper from above + break; + + case MT_SPINCUSHION: + if (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) + { + if (player->pflags & PF_BOUNCING) + { + toucher->momz = -toucher->momz; + P_DoAbilityBounce(player, false); + return; + } + else if (P_DamageMobj(toucher, special, special, 1, DMG_SPIKE)) + return; // Cannot hit sharp from above + } + break; + case MT_FANG: + if (!player->powers[pw_flashing] + && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) + && !(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + { + if ((special->state == &states[S_FANG_BOUNCE3] + || special->state == &states[S_FANG_BOUNCE4] + || special->state == &states[S_FANG_PINCHBOUNCE3] + || special->state == &states[S_FANG_PINCHBOUNCE4]) + && P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > 0) + { + P_DamageMobj(toucher, special, special, 1, 0); + P_SetTarget(&special->tracer, toucher); + + if (special->state == &states[S_FANG_PINCHBOUNCE3] + || special->state == &states[S_FANG_PINCHBOUNCE4]) + P_SetMobjState(special, S_FANG_PINCHPATHINGSTART2); + else + { + var1 = var2 = 4; + A_Boss5ExtraRepeat(special); + P_SetMobjState(special, S_FANG_PATHINGCONT2); //S_FANG_PATHINGCONT1 if you want him to drop a bomb on the player + } + if (special->eflags & MFE_VERTICALFLIP) + special->z = toucher->z - special->height; + else + special->z = toucher->z + toucher->height; + return; + } + } + break; + default: + break; } if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING)) From b9611c3a8130974122727b11cf73584ba35b5245 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 19:16:30 +0100 Subject: [PATCH 29/38] Hardcoded the cork's stun-you-even-while-flashing behaviour --- src/p_inter.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 70050a4cd..68f1782c5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3390,9 +3390,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] // ignore bouncing & such in invulnerability || player->powers[pw_super]) { - if (force || (inflictor && (inflictor->flags & MF_MISSILE) - && (inflictor->flags2 & MF2_SUPERFIRE) - && player->powers[pw_super])) + if (force + || (player->powers[pw_super] + && inflictor && inflictor->flags & MF_MISSILE && inflictor->flags2 & MF2_SUPERFIRE) // Super Sonic is stunned! + || (player->powers[pw_flashing] + && source && source->type == MT_FANG && inflictor && inflictor->type == MT_CORK)) // Fang's cork bullets knock you back even when flashing { #ifdef HAVE_BLUA if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) @@ -3400,8 +3402,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_SuperDamage(player, inflictor, source, damage); return true; } - else - return false; + return false; } #ifdef HAVE_BLUA else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) From ee0c4b42a601d2ebd55dcb0e71179c68b1c9c863 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 21:03:15 +0100 Subject: [PATCH 30/38] fix P_CheckSight to consider FOFs that completely block the view (this could probably be in its own branch to be tested properly, but I'm on a roll with this atm) --- src/p_sight.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/p_sight.c b/src/p_sight.c index 556041585..579b94e56 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -254,7 +254,8 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) // no wall to block sight with? if ((front = seg->frontsector)->floorheight == (back = seg->backsector)->floorheight && - front->ceilingheight == back->ceilingheight) + front->ceilingheight == back->ceilingheight + && !front->ffloors && !back->ffloors) continue; // possible occluder @@ -288,6 +289,41 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) if (los->topslope <= los->bottomslope) return false; + + // Monster Iestyn: check FOFs! + if (front->ffloors || back->ffloors) + { + ffloor_t *rover; + fixed_t topslope, bottomslope; + // check front sector's FOFs first + for (rover = front->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) + || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + { + continue; + } + topslope = FixedDiv(*rover->topheight - los->sightzstart , frac); + bottomslope = FixedDiv(*rover->bottomheight - los->sightzstart , frac); + if (topslope >= los->topslope && bottomslope <= los->bottomslope) + return false; // view completely blocked + } + // check back sector's FOFs as well + for (rover = back->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) + || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + { + continue; + } + topslope = FixedDiv(*rover->topheight - los->sightzstart , frac); + bottomslope = FixedDiv(*rover->bottomheight - los->sightzstart , frac); + if (topslope >= los->topslope && bottomslope <= los->bottomslope) + return false; // view completely blocked + } + // TODO: figure out if it's worth considering partially blocked cases or not? + // maybe to adjust los's top/bottom slopes if needed + } } // passed the subsector ok From ea951eef78bce86365a503ad83f4c49a2a2e0e40 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 21:16:44 +0100 Subject: [PATCH 31/38] fix an inconsistency I introduced between counting the waypoints and finding them again --- src/p_enemy.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index c983a0dc3..adc0f88f0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -12042,12 +12042,15 @@ void A_Boss5FindWaypoint(mobj_t *actor) { if (avoidcenter) continue; - waypoints[numwaypoints++] = mapthings[i].mobj; } else if (mapthings[i].mobj->reactiontime > 0) + { mapthings[i].mobj->reactiontime--; - else if (P_CheckSight(actor, mapthings[i].mobj)) - waypoints[numwaypoints++] = mapthings[i].mobj; + continue; + } + if (!P_CheckSight(actor, mapthings[i].mobj)) + continue; + waypoints[numwaypoints++] = mapthings[i].mobj; } if (actor->extravalue2 > 1) From 742b11c0ff8c7982f176019d0a71a8ed79824c8c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 21 May 2019 21:51:19 +0100 Subject: [PATCH 32/38] Hardcoded ACZ3.wad's version of A_TNTExplode under the name of A_Boss5BombExplode. After a lot of confusion and silly misunderstandings on my part (as well as a lot of mess cleaning), I've finally got there! The states for the actual bomb explosion effect itself are yet to be hardcoded, but that I'll do tomorrow afternoon probably. --- src/dehacked.c | 1 + src/info.h | 1 + src/p_enemy.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index dc30f7c7a..0af1520fd 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2236,6 +2236,7 @@ static actionpointer_t actionpointers[] = {{A_Boss5PinchShot}, "A_BOSS5PINCHSHOT"}, {{A_Boss5MakeItRain}, "A_BOSS5MAKEITRAIN"}, {{A_LookForBetter}, "A_LOOKFORBETTER"}, + {{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"}, {{NULL}, "NONE"}, diff --git a/src/info.h b/src/info.h index 6d115d564..b3cbba78f 100644 --- a/src/info.h +++ b/src/info.h @@ -250,6 +250,7 @@ void A_Boss5CheckFalling(); void A_Boss5PinchShot(); void A_Boss5MakeItRain(); void A_LookForBetter(); +void A_Boss5BombExplode(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 256 diff --git a/src/p_enemy.c b/src/p_enemy.c index adc0f88f0..664e3b9b0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -279,6 +279,7 @@ void A_Boss5CheckFalling(mobj_t *actor); void A_Boss5PinchShot(mobj_t *actor); void A_Boss5MakeItRain(mobj_t *actor); void A_LookForBetter(mobj_t *actor); +void A_Boss5BombExplode(mobj_t *actor); //for p_enemy.c // @@ -12440,3 +12441,83 @@ void A_LookForBetter(mobj_t *actor) P_LookForPlayers(actor, (locvar1 & 65535), false, FixedMul((locvar1 >> 16)*FRACUNIT, actor->scale)); A_FaceTarget(actor); } + +/* * Spawns a dust ring. + * The dust ring behaves slightly randomly so it doesn't look too uniform. + * + * \param mobjtype Thing type to make a ring of. + * \param div Amount of things to spawn on the ring. + * \param x Center X coordinates. + * \param y Center Y coordinates. + * \param z Center Z coordinates. + * \param radius Radius. + * \param speed Additional thrust on particles. + * \param scale 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) +{ + angle_t ang = FixedAngle(FixedDiv(360*FRACUNIT, div*FRACUNIT)); //(ANGLE_180/div)*2; + UINT32 i; + + // it turned out the radius was effectively nullified thanks to errors in the original script + // BUT people preferred how it looked before I "fixed" it, so I got rid of the radius calculations altogether + // this was a bit of a mess to sort out, but at least it's probably somewhat fine now? + // -- Monster Iestyn (21/05/19) + (void)radius; + + for (i = 0; i < div; i++) + { + mobj_t *dust = P_SpawnMobj( + x, //+ FixedMul(radius, FINECOSINE((ang*i) >> ANGLETOFINESHIFT)), + y, //+ FixedMul(radius, FINESINE((ang*i) >> ANGLETOFINESHIFT)), + z, + mobjtype + ); + + dust->angle = ang*i + ANGLE_90; + P_SetScale(dust, scale); + dust->destscale = FixedMul(4*FRACUNIT + P_RandomFixed(), scale); + dust->scalespeed = scale/24; + P_Thrust(dust, ang*i, speed + FixedMul(P_RandomFixed(), scale)); + dust->momz = P_SignedRandom()*scale/64; + } +} + +// Function: A_Boss5BombExplode +// +// Description: Boss 5's bomb exploding. +// +// var1 = Thing type to spawn as dust +// var2 = unused +// +void A_Boss5BombExplode(mobj_t *actor) +{ + INT32 locvar1 = var1; + //INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Boss5BombExplode", actor)) + return; +#endif + + // The original Lua script did not use |= to add flags but just set these flags exactly apparently? + // (I may modify this later) + // -- Monster Iestyn (21/05/19) + actor->flags = MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP; + actor->flags2 = MF2_EXPLOSION; + + 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_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; + quake.time = TICRATE/6; + // the following quake values have no effect atm? ah well, may as well set them anyway + { + mappoint_t q_epicenter = {actor->x, actor->y, actor->z}; + quake.epicenter = &q_epicenter; + } + quake.radius = 20*actor->radius; +} From e60b0b1a80b06f28166d58ffaa50015e3bd7caff Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 23 May 2019 21:08:27 +0100 Subject: [PATCH 33/38] Update hw_light.c (though I'm not sure why we bother, since coronas have been disabled for a decade now) --- src/hardware/hw_light.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 2515c6a86..16929dd5e 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -199,7 +199,9 @@ light_t *t_lspr[NUMSPRITES] = &lspr[REDBALL_L], // SPR_EFIR // Boss 5 (Arid Canyon) - &lspr[NOLIGHT], // SPR_EGGQ + &lspr[NOLIGHT], //SPR_FANG // replaces EGGQ + &lspr[NOLIGHT], //SPR_FBOM + &lspr[NOLIGHT], //SPR_FSGN // Boss 6 (Red Volcano) &lspr[NOLIGHT], // SPR_EEGR From 677801f5fffe99137a17f98b57c762928b27f677 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 23 May 2019 21:51:58 +0100 Subject: [PATCH 34/38] Hardcode the bomb's explosion states, the dust object type and states, and the sprite prefixes for both --- src/dehacked.c | 15 ++++++++++++++ src/hardware/hw_light.c | 2 ++ src/info.c | 44 ++++++++++++++++++++++++++++++++++++++++- src/info.h | 17 ++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index ab79b21a1..6d1f58990 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4788,6 +4788,20 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FBOMB1", "S_FBOMB2", + "S_FBOMB_EXPL1", + "S_FBOMB_EXPL2", + "S_FBOMB_EXPL3", + "S_FBOMB_EXPL4", + "S_FBOMB_EXPL5", + "S_FBOMB_EXPL6", + "S_TNTDUST_1", + "S_TNTDUST_2", + "S_TNTDUST_3", + "S_TNTDUST_4", + "S_TNTDUST_5", + "S_TNTDUST_6", + "S_TNTDUST_7", + "S_TNTDUST_8", "S_FSGNA", "S_FSGNB", "S_FSGNC", @@ -7095,6 +7109,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Boss 5 "MT_FANG", "MT_FBOMB", + "MT_TNTDUST", // also used by barrel "MT_FSGNA", "MT_FSGNB", "MT_FANGWAYPOINT", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 16929dd5e..90d02fdf8 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -202,6 +202,8 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], //SPR_FANG // replaces EGGQ &lspr[NOLIGHT], //SPR_FBOM &lspr[NOLIGHT], //SPR_FSGN + &lspr[REDBALL_L], //SPR_BARX // bomb explosion (also used by barrel) + &lspr[NOLIGHT], //SPR_BARD // bomb dust (also used by barrel) // Boss 6 (Red Volcano) &lspr[NOLIGHT], // SPR_EEGR diff --git a/src/info.c b/src/info.c index 04b138e8b..e03b63a65 100644 --- a/src/info.c +++ b/src/info.c @@ -90,6 +90,8 @@ char sprnames[NUMSPRITES + 1][5] = "FANG", // replaces EGGQ "FBOM", "FSGN", + "BARX", // bomb explosion (also used by barrel) + "BARD", // bomb dust (also used by barrel) // Boss 6 (Red Volcano) "EGGR", @@ -1410,6 +1412,20 @@ state_t states[NUMSTATES] = {SPR_FBOM, 0, 1, {A_GhostMe}, 0, 0, S_FBOMB2}, // S_FBOMB1 {SPR_FBOM, 1, 1, {A_GhostMe}, 0, 0, S_FBOMB1}, // S_FBOMB2 + {SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_FBOMB_EXPL2}, // S_FBOMB_EXPL1 + {SPR_BARX, 1|FF_FULLBRIGHT, 2, {A_Boss5BombExplode}, MT_TNTDUST, 0, S_FBOMB_EXPL3}, // S_FBOMB_EXPL2 + {SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_FBOMB_EXPL4}, // S_FBOMB_EXPL3 + {SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FBOMB_EXPL5}, // S_FBOMB_EXPL4 + {SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FBOMB_EXPL6}, // S_FBOMB_EXPL5 + {SPR_NULL, 0, 2*TICRATE, {NULL}, 0, 0, S_NULL}, // S_FBOMB_EXPL6 + {SPR_BARD, 0|FF_TRANS90, 2, {NULL}, 0, 0, S_TNTDUST_2}, // S_TNTDUST_1 + {SPR_BARD, 0|FF_TRANS30, 2*TICRATE, {A_SetRandomTics}, 2, TICRATE, S_TNTDUST_3}, // S_TNTDUST_2 + {SPR_BARD, 0|FF_TRANS40, 10, {NULL}, 0, 0, S_TNTDUST_4}, // S_TNTDUST_3 + {SPR_BARD, 0|FF_TRANS50, 10, {NULL}, 0, 0, S_TNTDUST_5}, // S_TNTDUST_4 + {SPR_BARD, 0|FF_TRANS60, 10, {NULL}, 0, 0, S_TNTDUST_6}, // S_TNTDUST_5 + {SPR_BARD, 0|FF_TRANS70, 10, {NULL}, 0, 0, S_TNTDUST_7}, // S_TNTDUST_6 + {SPR_BARD, 0|FF_TRANS80, 10, {NULL}, 0, 0, S_TNTDUST_8}, // S_TNTDUST_7 + {SPR_BARD, 0|FF_TRANS90, 10, {NULL}, 0, 0, S_NULL}, // S_TNTDUST_8 {SPR_FSGN, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNA {SPR_FSGN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNB {SPR_FSGN, 2|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_FSGNC @@ -5398,7 +5414,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, //S_TNTBARREL_EXPL1, // deathstate + S_FBOMB_EXPL1, // deathstate S_NULL, // xdeathstate sfx_s3k4e, // deathsound 20*FRACUNIT, // speed @@ -5412,6 +5428,32 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_TNTDUST + -1, // doomednum + S_TNTDUST_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 + 20*FRACUNIT, // speed + 16*FRACUNIT, // radius + 32*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_FSGNA -1, // doomednum S_FSGNA, // spawnstate diff --git a/src/info.h b/src/info.h index ad8d138e6..fbe8ed8d7 100644 --- a/src/info.h +++ b/src/info.h @@ -321,6 +321,8 @@ typedef enum sprite SPR_FANG, // replaces EGGQ SPR_FBOM, SPR_FSGN, + SPR_BARX, // bomb explosion (also used by barrel) + SPR_BARD, // bomb dust (also used by barrel) // Boss 6 (Red Volcano) SPR_EGGR, @@ -1531,6 +1533,20 @@ typedef enum state S_FBOMB1, S_FBOMB2, + S_FBOMB_EXPL1, + S_FBOMB_EXPL2, + S_FBOMB_EXPL3, + S_FBOMB_EXPL4, + S_FBOMB_EXPL5, + S_FBOMB_EXPL6, + S_TNTDUST_1, + S_TNTDUST_2, + S_TNTDUST_3, + S_TNTDUST_4, + S_TNTDUST_5, + S_TNTDUST_6, + S_TNTDUST_7, + S_TNTDUST_8, S_FSGNA, S_FSGNB, S_FSGNC, @@ -3858,6 +3874,7 @@ typedef enum mobj_type // Boss 5 MT_FANG, MT_FBOMB, + MT_TNTDUST, // also used by barrel MT_FSGNA, MT_FSGNB, MT_FANGWAYPOINT, From ad4006712e16e0932ce110aa36a99029d805210a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 5 May 2019 21:03:15 +0100 Subject: [PATCH 35/38] fix P_CheckSight to consider FOFs that completely block the view (this could probably be in its own branch to be tested properly, but I'm on a roll with this atm) --- src/p_sight.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/p_sight.c b/src/p_sight.c index 556041585..579b94e56 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -254,7 +254,8 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) // no wall to block sight with? if ((front = seg->frontsector)->floorheight == (back = seg->backsector)->floorheight && - front->ceilingheight == back->ceilingheight) + front->ceilingheight == back->ceilingheight + && !front->ffloors && !back->ffloors) continue; // possible occluder @@ -288,6 +289,41 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) if (los->topslope <= los->bottomslope) return false; + + // Monster Iestyn: check FOFs! + if (front->ffloors || back->ffloors) + { + ffloor_t *rover; + fixed_t topslope, bottomslope; + // check front sector's FOFs first + for (rover = front->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) + || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + { + continue; + } + topslope = FixedDiv(*rover->topheight - los->sightzstart , frac); + bottomslope = FixedDiv(*rover->bottomheight - los->sightzstart , frac); + if (topslope >= los->topslope && bottomslope <= los->bottomslope) + return false; // view completely blocked + } + // check back sector's FOFs as well + for (rover = back->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) + || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + { + continue; + } + topslope = FixedDiv(*rover->topheight - los->sightzstart , frac); + bottomslope = FixedDiv(*rover->bottomheight - los->sightzstart , frac); + if (topslope >= los->topslope && bottomslope <= los->bottomslope) + return false; // view completely blocked + } + // TODO: figure out if it's worth considering partially blocked cases or not? + // maybe to adjust los's top/bottom slopes if needed + } } // passed the subsector ok From abfdac15a8582c8f28cb11ad609cfca4d0e4d7c4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 27 May 2019 20:36:35 +0100 Subject: [PATCH 36/38] Fixed P_CheckSight to support slopes, both for normal planes and FOF planes (Untested) --- src/p_sight.c | 68 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/src/p_sight.c b/src/p_sight.c index 579b94e56..1b3ff0cf9 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -14,6 +14,7 @@ #include "doomdef.h" #include "doomstat.h" #include "p_local.h" +#include "p_slopes.h" #include "r_main.h" #include "r_state.h" @@ -216,6 +217,10 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) const sector_t *front, *back; const vertex_t *v1,*v2; fixed_t frac; + fixed_t frontf, backf, frontc, backc; +#ifdef ESLOPE + fixed_t fracx, fracy; +#endif // already checked other side? if (line->validcount == validcount) @@ -250,37 +255,51 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) if (!(line->flags & ML_TWOSIDED)) return false; + // calculate fractional intercept (how far along we are divided by how far we are from t2) + frac = P_InterceptVector2(&los->strace, &divl); + + front = seg->frontsector; + back = seg->backsector; +#ifdef ESLOPE + // calculate position at intercept + fracx = los->strace.x + FixedMul(los->strace.dx, frac); + fracy = los->strace.y + FixedMul(los->strace.dy, frac); + // calculate sector heights + frontf = (front->f_slope) ? P_GetZAt(front->f_slope, fracx, fracy) : front->floorheight; + frontc = (front->c_slope) ? P_GetZAt(front->c_slope, fracx, fracy) : front->ceilingheight; + backf = (back->f_slope) ? P_GetZAt(back->f_slope, fracx, fracy) : back->floorheight; + backc = (back->c_slope) ? P_GetZAt(back->c_slope, fracx, fracy) : back->ceilingheight; +#else + frontf = front->floorheight; + frontc = front->ceilingheight; + backf = back->floorheight; + backc = back->ceilingheight; +#endif // crosses a two sided line // no wall to block sight with? - if ((front = seg->frontsector)->floorheight == - (back = seg->backsector)->floorheight && - front->ceilingheight == back->ceilingheight - && !front->ffloors && !back->ffloors) + if (frontf == backf && frontc == backc + && !front->ffloors & !back->ffloors) // (and no FOFs) continue; // possible occluder // because of ceiling height differences - popentop = front->ceilingheight < back->ceilingheight ? - front->ceilingheight : back->ceilingheight ; + popentop = min(frontc, backc); // because of floor height differences - popenbottom = front->floorheight > back->floorheight ? - front->floorheight : back->floorheight ; + popenbottom = max(frontf, backf); // quick test for totally closed doors if (popenbottom >= popentop) return false; - frac = P_InterceptVector2(&los->strace, &divl); - - if (front->floorheight != back->floorheight) + if (frontf != backf) { fixed_t slope = FixedDiv(popenbottom - los->sightzstart , frac); if (slope > los->bottomslope) los->bottomslope = slope; } - if (front->ceilingheight != back->ceilingheight) + if (frontc != backc) { fixed_t slope = FixedDiv(popentop - los->sightzstart , frac); if (slope < los->topslope) @@ -295,6 +314,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) { ffloor_t *rover; fixed_t topslope, bottomslope; + fixed_t topz, bottomz; // check front sector's FOFs first for (rover = front->ffloors; rover; rover = rover->next) { @@ -303,8 +323,16 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) { continue; } - topslope = FixedDiv(*rover->topheight - los->sightzstart , frac); - bottomslope = FixedDiv(*rover->bottomheight - los->sightzstart , frac); + +#ifdef ESLOPE + topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; + bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; +#else + topz = *rover->topheight; + bottomz = *rover->bottomheight; +#endif + topslope = FixedDiv(topz - los->sightzstart , frac); + bottomslope = FixedDiv(bottomz - los->sightzstart , frac); if (topslope >= los->topslope && bottomslope <= los->bottomslope) return false; // view completely blocked } @@ -316,8 +344,16 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) { continue; } - topslope = FixedDiv(*rover->topheight - los->sightzstart , frac); - bottomslope = FixedDiv(*rover->bottomheight - los->sightzstart , frac); + +#ifdef ESLOPE + topz = (*rover->t_slope) ? P_GetZAt(*rover->t_slope, fracx, fracy) : *rover->topheight; + bottomz = (*rover->b_slope) ? P_GetZAt(*rover->b_slope, fracx, fracy) : *rover->bottomheight; +#else + topz = *rover->topheight; + bottomz = *rover->bottomheight; +#endif + topslope = FixedDiv(topz - los->sightzstart , frac); + bottomslope = FixedDiv(bottomz - los->sightzstart , frac); if (topslope >= los->topslope && bottomslope <= los->bottomslope) return false; // view completely blocked } From 571c5b89b5739795386b81f0554c4655a9cad4e4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 27 May 2019 21:18:02 +0100 Subject: [PATCH 37/38] Whoops, forgot to make P_CheckSight support slopes for same-sector FOF plane checking. --- src/p_sight.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/p_sight.c b/src/p_sight.c index 1b3ff0cf9..aa59314f1 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -470,6 +470,8 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) if (s1 == s2) // Both sectors are the same. { ffloor_t *rover; + fixed_t topz1, bottomz1; // top, bottom heights at t1's position + fixed_t topz2, bottomz2; // likewise but for t2 for (rover = s1->ffloors; rover; rover = rover->next) { @@ -482,9 +484,30 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) continue; } +#ifdef ESLOPE + if (*rover->t_slope) + { + topz1 = P_GetZAt(*rover->t_slope, t1->x, t1->y); + topz2 = P_GetZAt(*rover->t_slope, t2->x, t2->y); + } + else + topz1 = topz2 = *rover->topheight; + + if (*rover->b_slope) + { + bottomz1 = P_GetZAt(*rover->b_slope, t1->x, t1->y); + bottomz2 = P_GetZAt(*rover->b_slope, t2->x, t2->y); + } + else + bottomz1 = bottomz2 = *rover->bottomheight; +#else + topz1 = topz2 = *rover->topheight; + bottomz1 = bottomz2 = *rover->bottomheight; +#endif + // Check for blocking floors here. - if ((los.sightzstart < *rover->bottomheight && t2->z >= *rover->topheight) - || (los.sightzstart >= *rover->topheight && t2->z + t2->height < *rover->bottomheight)) + if ((los.sightzstart < bottomz1 && t2->z >= topz2) + || (los.sightzstart >= topz1 && t2->z + t2->height < bottomz2)) { // no way to see through that return false; @@ -495,19 +518,19 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) if (!(rover->flags & FF_INVERTPLANES)) { - if (los.sightzstart >= *rover->topheight && t2->z + t2->height < *rover->topheight) + if (los.sightzstart >= topz1 && t2->z + t2->height < topz2) return false; // blocked by upper outside plane - if (los.sightzstart < *rover->bottomheight && t2->z >= *rover->bottomheight) + if (los.sightzstart < bottomz1 && t2->z >= bottomz2) return false; // blocked by lower outside plane } if (rover->flags & FF_INVERTPLANES || rover->flags & FF_BOTHPLANES) { - if (los.sightzstart < *rover->topheight && t2->z >= *rover->topheight) + if (los.sightzstart < topz1 && t2->z >= topz2) return false; // blocked by upper inside plane - if (los.sightzstart >= *rover->bottomheight && t2->z + t2->height < *rover->bottomheight) + if (los.sightzstart >= bottomz1 && t2->z + t2->height < bottomz2) return false; // blocked by lower inside plane } } From 0fd36681111a9ae7cdc48438de5a2f7813a3e480 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 4 Jun 2019 17:34:59 +0000 Subject: [PATCH 38/38] Revert "Merge branch '144-scrolltweaks' into 'master'" This reverts merge request !213 --- src/p_spec.c | 145 ++++++++++++++------------------------------------- 1 file changed, 38 insertions(+), 107 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index f8aefb9c8..e47b5cc03 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7746,22 +7746,11 @@ static void P_SpawnScrollers(void) for (i = 0; i < numlines; i++, l++) { - fixed_t dx = l->dx; // direction and speed of scrolling - fixed_t dy = l->dy; + fixed_t dx = l->dx >> SCROLL_SHIFT; // direction and speed of scrolling + fixed_t dy = l->dy >> SCROLL_SHIFT; INT32 control = -1, accel = 0; // no control sector or acceleration INT32 special = l->special; - // If front texture X offset provided, override the amount with it. - if (sides[l->sidenum[0]].textureoffset != 0) - { - fixed_t len = sides[l->sidenum[0]].textureoffset; - fixed_t h = FixedHypot(dx, dy); - dx = FixedMul(FixedDiv(dx, h), len); - dy = FixedMul(FixedDiv(dy, h), len); - } - dx = dx >> SCROLL_SHIFT; - dy = dy >> SCROLL_SHIFT; - // These types are same as the ones they get set to except that the // first side's sector's heights cause scrolling when they change, and // this linedef controls the direction and speed of the scrolling. The @@ -7796,14 +7785,8 @@ static void P_SpawnScrollers(void) case 513: // scroll effect ceiling case 533: // scroll and carry objects on ceiling - if (l->tag == 0) - Add_Scroller(sc_ceiling, -dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - } - + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 533) break; /* FALLTHRU */ @@ -7811,26 +7794,14 @@ static void P_SpawnScrollers(void) case 523: // carry objects on ceiling dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - - if (l->tag == 0) - Add_Scroller(sc_carry_ceiling, dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - } + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; case 510: // scroll effect floor case 530: // scroll and carry objects on floor - if (l->tag == 0) - Add_Scroller(sc_floor, -dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - } - + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 530) break; /* FALLTHRU */ @@ -7838,14 +7809,8 @@ static void P_SpawnScrollers(void) case 520: // carry objects on floor dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - - if (l->tag == 0) - Add_Scroller(sc_carry, dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); - } + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; // scroll wall according to linedef @@ -9208,77 +9173,43 @@ static void P_SpawnPushers(void) line_t *l = lines; register INT32 s; mobj_t *thing; - pushertype_e pushertype; - fixed_t dx, dy; for (i = 0; i < numlines; i++, l++) - { switch (l->special) { - case 541: // wind - pushertype = p_wind; - break; - - case 544: // current - pushertype = p_current; - break; - case 547: // push/pull - if (l->tag == 0) - { - s = l->frontsector - sectors; - if ((thing = P_GetPushThing(s)) != NULL) // No MT_P* means no effect - Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - } - else + case 541: // wind + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 544: // current + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 547: // push/pull for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) { - if ((thing = P_GetPushThing(s)) != NULL) // No MT_P* means no effect + thing = P_GetPushThing(s); + if (thing) // No MT_P* means no effect Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); } - - continue; - - case 545: // current up - pushertype = p_upcurrent; - break; - - case 546: // current down - pushertype = p_downcurrent; - break; - - case 542: // wind up - pushertype = p_upwind; - break; - - case 543: // wind down - pushertype = p_downwind; - break; - - default: - continue; + break; + case 545: // current up + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 546: // current down + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 542: // wind up + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; + case 543: // wind down + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); + break; } - - dx = l->dx; - dy = l->dy; - - // Obtain versor and scale it up according to texture offset, if provided; line length is ignored in this case. - - if (sides[l->sidenum[0]].textureoffset != 0) - { - fixed_t len = sides[l->sidenum[0]].textureoffset; - fixed_t h = FixedHypot(dx, dy); - dx = FixedMul(FixedDiv(dx, h), len); - dy = FixedMul(FixedDiv(dy, h), len); - } - - if (l->tag == 0) - Add_Pusher(pushertype, dx, dy, NULL, l->frontsector - sectors, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - else - { - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Pusher(pushertype, dx, dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); - } - } } static void P_SearchForDisableLinedefs(void)