mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 17:22:12 +00:00
Merge branch 'master' into checksight-fixes
# Conflicts: # src/p_sight.c
This commit is contained in:
commit
b7f75246e4
8 changed files with 1400 additions and 86 deletions
110
src/dehacked.c
110
src/dehacked.c
|
@ -2381,6 +2381,18 @@ 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"},
|
||||
{{A_Boss5ExtraRepeat}, "A_BOSS5EXTRAREPEAT"},
|
||||
{{A_Boss5Calm}, "A_BOSS5CALM"},
|
||||
{{A_Boss5CheckOnGround}, "A_BOSS5CHECKONGROUND"},
|
||||
{{A_Boss5CheckFalling}, "A_BOSS5CHECKFALLING"},
|
||||
{{A_Boss5PinchShot}, "A_BOSS5PINCHSHOT"},
|
||||
{{A_Boss5MakeItRain}, "A_BOSS5MAKEITRAIN"},
|
||||
{{A_LookForBetter}, "A_LOOKFORBETTER"},
|
||||
{{A_Boss5BombExplode}, "A_BOSS5BOMBEXPLODE"},
|
||||
|
||||
{{NULL}, "NONE"},
|
||||
|
||||
|
@ -4704,6 +4716,96 @@ 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_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_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",
|
||||
|
||||
// Black Eggman (Boss 7)
|
||||
"S_BLACKEGG_STND",
|
||||
"S_BLACKEGG_STND2",
|
||||
|
@ -7004,6 +7106,14 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_EGGMOBILE4_MACE",
|
||||
"MT_JETFLAME",
|
||||
|
||||
// Boss 5
|
||||
"MT_FANG",
|
||||
"MT_FBOMB",
|
||||
"MT_TNTDUST", // also used by barrel
|
||||
"MT_FSGNA",
|
||||
"MT_FSGNB",
|
||||
"MT_FANGWAYPOINT",
|
||||
|
||||
// Black Eggman (Boss 7)
|
||||
"MT_BLACKEGGMAN",
|
||||
"MT_BLACKEGGMAN_HELPER",
|
||||
|
|
|
@ -199,7 +199,11 @@ 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
|
||||
&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
|
||||
|
|
276
src/info.c
276
src/info.c
|
@ -87,7 +87,11 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"EFIR", // Boss 4 jet flame
|
||||
|
||||
// Boss 5 (Arid Canyon)
|
||||
"EGGQ",
|
||||
"FANG", // replaces EGGQ
|
||||
"FBOM",
|
||||
"FSGN",
|
||||
"BARX", // bomb explosion (also used by barrel)
|
||||
"BARD", // bomb dust (also used by barrel)
|
||||
|
||||
// Boss 6 (Red Volcano)
|
||||
"EGGR",
|
||||
|
@ -1318,6 +1322,115 @@ 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+(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
|
||||
|
||||
{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, (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
|
||||
|
||||
{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_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
|
||||
|
||||
// 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
|
||||
|
@ -5261,6 +5374,167 @@ 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_FBOMB_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_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
|
||||
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_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
|
||||
|
|
116
src/info.h
116
src/info.h
|
@ -239,6 +239,18 @@ void A_WhoCaresIfYourSonIsABee();
|
|||
void A_ParentTriesToSleep();
|
||||
void A_CryingToMomma();
|
||||
void A_CheckFlags2();
|
||||
void A_Boss5FindWaypoint();
|
||||
void A_DoNPCSkid();
|
||||
void A_DoNPCPain();
|
||||
void A_PrepareRepeat();
|
||||
void A_Boss5ExtraRepeat();
|
||||
void A_Boss5Calm();
|
||||
void A_Boss5CheckOnGround();
|
||||
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
|
||||
|
@ -306,7 +318,11 @@ typedef enum sprite
|
|||
SPR_EFIR, // Boss 4 jet flame
|
||||
|
||||
// Boss 5 (Arid Canyon)
|
||||
SPR_EGGQ,
|
||||
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,
|
||||
|
@ -1445,6 +1461,96 @@ 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_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_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,
|
||||
|
||||
// Black Eggman (Boss 7)
|
||||
S_BLACKEGG_STND,
|
||||
S_BLACKEGG_STND2,
|
||||
|
@ -3765,6 +3871,14 @@ typedef enum mobj_type
|
|||
MT_EGGMOBILE4_MACE,
|
||||
MT_JETFLAME,
|
||||
|
||||
// Boss 5
|
||||
MT_FANG,
|
||||
MT_FBOMB,
|
||||
MT_TNTDUST, // also used by barrel
|
||||
MT_FSGNA,
|
||||
MT_FSGNB,
|
||||
MT_FANGWAYPOINT,
|
||||
|
||||
// Black Eggman (Boss 7)
|
||||
MT_BLACKEGGMAN,
|
||||
MT_BLACKEGGMAN_HELPER,
|
||||
|
|
757
src/p_enemy.c
757
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
|
||||
|
@ -266,6 +268,18 @@ 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);
|
||||
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_Boss5MakeItRain(mobj_t *actor);
|
||||
void A_LookForBetter(mobj_t *actor);
|
||||
void A_Boss5BombExplode(mobj_t *actor);
|
||||
//for p_enemy.c
|
||||
|
||||
//
|
||||
|
@ -3549,59 +3563,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)
|
||||
|
@ -11852,3 +11910,614 @@ void A_CheckFlags2(mobj_t *actor)
|
|||
if (actor->flags2 & locvar1)
|
||||
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;
|
||||
UINT32 i;
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_Boss5FindWaypoint", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
avoidcenter = !actor->tracer || (actor->health == actor->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;
|
||||
if (!P_CheckSight(actor, mapthings[i].mobj))
|
||||
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;
|
||||
}
|
||||
else if (mapthings[i].mobj->reactiontime > 0)
|
||||
{
|
||||
mapthings[i].mobj->reactiontime--;
|
||||
continue;
|
||||
}
|
||||
if (!P_CheckSight(actor, mapthings[i].mobj))
|
||||
continue;
|
||||
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)
|
||||
{
|
||||
Z_Free(waypoints); // free table
|
||||
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.
|
||||
//
|
||||
// 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->z;
|
||||
|
||||
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.
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// 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_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.
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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_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.
|
||||
//
|
||||
// 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;
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_LookForBetter", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
117
src/p_inter.c
117
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))
|
||||
|
@ -3352,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))
|
||||
|
@ -3362,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))
|
||||
|
|
52
src/p_map.c
52
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)
|
||||
{
|
||||
|
|
52
src/p_mobj.c
52
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
|
||||
|
@ -7289,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!
|
||||
|
@ -7378,6 +7423,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;
|
||||
|
@ -9100,6 +9148,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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue