* Added boss enable linedef (type 449).
- Frontside x offset = boss ID (determined via parameter for all bosses) - Noclimb flag = disable mode - Bosses don't do a fuckin' THING - no state updates, no player searches, no sounds, no lua, no nothin' - and it's all totally netsynced. - The only thing they WILL do is flash infinitely if you hurt them, but this is designed for stuff where you're not meant to be in the same room as the boss til it's activated. - All bosses of all IDs are automatically enabled on mapload, then if an enable mode version of this linedef is present in the map for a specific boss id, that boss id is automatically disabled. * Add multi-boss support via parameter for: - All bosses' MT_BOSSFLYPOINT search - Boss 5's waypoint search - Oldbrak's waypoint search (this one's for you, jood)
This commit is contained in:
parent
b77780e1e7
commit
7cb02985f4
|
@ -3878,6 +3878,8 @@ bossjustdie:
|
||||||
}
|
}
|
||||||
default: //eggmobiles
|
default: //eggmobiles
|
||||||
{
|
{
|
||||||
|
UINT8 extrainfo = (mo->spawnpoint ? mo->spawnpoint->extrainfo : 0);
|
||||||
|
|
||||||
// Stop exploding and prepare to run.
|
// Stop exploding and prepare to run.
|
||||||
P_SetMobjState(mo, mo->info->xdeathstate);
|
P_SetMobjState(mo, mo->info->xdeathstate);
|
||||||
if (P_MobjWasRemoved(mo))
|
if (P_MobjWasRemoved(mo))
|
||||||
|
@ -3897,6 +3899,9 @@ bossjustdie:
|
||||||
if (mo2->type != MT_BOSSFLYPOINT)
|
if (mo2->type != MT_BOSSFLYPOINT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (mo2->spawnpoint && mo2->spawnpoint->extrainfo != extrainfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
// If this one's further then the last one, don't go for it.
|
// If this one's further then the last one, don't go for it.
|
||||||
if (mo->target &&
|
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 - mo2->x, mo->y - mo2->y), mo->z - mo2->z) >
|
||||||
|
@ -12303,6 +12308,7 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
||||||
//INT32 locvar2 = var2;
|
//INT32 locvar2 = var2;
|
||||||
boolean avoidcenter;
|
boolean avoidcenter;
|
||||||
UINT32 i;
|
UINT32 i;
|
||||||
|
UINT8 extrainfo = (actor->spawnpoint ? actor->spawnpoint->extrainfo : 0);
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_CallAction("A_Boss5FindWaypoint", actor))
|
if (LUA_CallAction("A_Boss5FindWaypoint", actor))
|
||||||
return;
|
return;
|
||||||
|
@ -12312,16 +12318,34 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
||||||
|
|
||||||
if (locvar1 == 2) // look for the boss waypoint
|
if (locvar1 == 2) // look for the boss waypoint
|
||||||
{
|
{
|
||||||
for (i = 0; i < nummapthings; i++)
|
thinker_t *th;
|
||||||
|
mobj_t *mo2;
|
||||||
|
P_SetTarget(&actor->tracer, NULL);
|
||||||
|
// Flee! Flee! Find a point to escape to! If none, just shoot upward!
|
||||||
|
// scan the thinkers to find the runaway point
|
||||||
|
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||||
{
|
{
|
||||||
if (!mapthings[i].mobj)
|
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||||
continue;
|
continue;
|
||||||
if (mapthings[i].mobj->type != MT_BOSSFLYPOINT)
|
|
||||||
|
mo2 = (mobj_t *)th;
|
||||||
|
|
||||||
|
if (mo2->type != MT_BOSSFLYPOINT)
|
||||||
continue;
|
continue;
|
||||||
P_SetTarget(&actor->tracer, mapthings[i].mobj);
|
|
||||||
break;
|
if (mo2->spawnpoint && mo2->spawnpoint->extrainfo != extrainfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If this one's further then the last one, don't go for it.
|
||||||
|
if (actor->tracer &&
|
||||||
|
P_AproxDistance(P_AproxDistance(actor->x - mo2->x, actor->y - mo2->y), actor->z - mo2->z) >
|
||||||
|
P_AproxDistance(P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Otherwise... Do!
|
||||||
|
P_SetTarget(&actor->tracer, mo2);
|
||||||
}
|
}
|
||||||
if (i == nummapthings)
|
if (!actor->tracer)
|
||||||
return; // no boss flypoints found
|
return; // no boss flypoints found
|
||||||
}
|
}
|
||||||
else if (locvar1 == 1) // always go to ambush-marked waypoint
|
else if (locvar1 == 1) // always go to ambush-marked waypoint
|
||||||
|
@ -12335,11 +12359,13 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
||||||
continue;
|
continue;
|
||||||
if (mapthings[i].mobj->type != MT_FANGWAYPOINT)
|
if (mapthings[i].mobj->type != MT_FANGWAYPOINT)
|
||||||
continue;
|
continue;
|
||||||
if (mapthings[i].options & MTF_AMBUSH)
|
if (mapthings[i].extrainfo != extrainfo)
|
||||||
{
|
continue;
|
||||||
P_SetTarget(&actor->tracer, mapthings[i].mobj);
|
if (!(mapthings[i].options & MTF_AMBUSH))
|
||||||
break;
|
continue;
|
||||||
}
|
|
||||||
|
P_SetTarget(&actor->tracer, mapthings[i].mobj);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == nummapthings)
|
if (i == nummapthings)
|
||||||
|
@ -12363,6 +12389,8 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
||||||
continue;
|
continue;
|
||||||
if (actor->tracer == mapthings[i].mobj) // this was your tracer last time
|
if (actor->tracer == mapthings[i].mobj) // this was your tracer last time
|
||||||
continue;
|
continue;
|
||||||
|
if (mapthings[i].extrainfo != extrainfo)
|
||||||
|
continue;
|
||||||
if (mapthings[i].options & MTF_AMBUSH)
|
if (mapthings[i].options & MTF_AMBUSH)
|
||||||
{
|
{
|
||||||
if (avoidcenter)
|
if (avoidcenter)
|
||||||
|
@ -12418,6 +12446,8 @@ void A_Boss5FindWaypoint(mobj_t *actor)
|
||||||
continue;
|
continue;
|
||||||
if (actor->tracer == mapthings[i].mobj) // this was your tracer last time
|
if (actor->tracer == mapthings[i].mobj) // this was your tracer last time
|
||||||
continue;
|
continue;
|
||||||
|
if (mapthings[i].extrainfo != extrainfo)
|
||||||
|
continue;
|
||||||
if (mapthings[i].options & MTF_AMBUSH)
|
if (mapthings[i].options & MTF_AMBUSH)
|
||||||
{
|
{
|
||||||
if (avoidcenter)
|
if (avoidcenter)
|
||||||
|
|
70
src/p_mobj.c
70
src/p_mobj.c
|
@ -5236,6 +5236,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
||||||
INT32 i;
|
INT32 i;
|
||||||
boolean foundgoop = false;
|
boolean foundgoop = false;
|
||||||
INT32 closestNum;
|
INT32 closestNum;
|
||||||
|
UINT8 extrainfo = (mobj->spawnpoint ? mobj->spawnpoint->extrainfo : 0);
|
||||||
|
|
||||||
// Looks for players in goop. If you find one, try to jump on him.
|
// Looks for players in goop. If you find one, try to jump on him.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
@ -5261,17 +5262,23 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mo2 = (mobj_t *)th;
|
mo2 = (mobj_t *)th;
|
||||||
if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint)
|
if (mo2->type != MT_BOSS3WAYPOINT)
|
||||||
{
|
continue;
|
||||||
dist = P_AproxDistance(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y);
|
if (!mo2->spawnpoint)
|
||||||
|
continue;
|
||||||
|
if (mo2->spawnpoint->extrainfo != extrainfo)
|
||||||
|
continue;
|
||||||
|
if (mobj->health <= mobj->info->damage && !(mo2->spawnpoint->options & 7))
|
||||||
|
continue; // don't jump to center
|
||||||
|
|
||||||
if (closestNum == -1 || dist < closestdist)
|
dist = P_AproxDistance(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y);
|
||||||
{
|
|
||||||
closestNum = (mo2->spawnpoint->options & 7);
|
if (!(closestNum == -1 || dist < closestdist))
|
||||||
closestdist = dist;
|
continue;
|
||||||
foundgoop = true;
|
|
||||||
}
|
closestNum = (mo2->spawnpoint->options & 7);
|
||||||
}
|
closestdist = dist;
|
||||||
|
foundgoop = true;
|
||||||
}
|
}
|
||||||
waypointNum = closestNum;
|
waypointNum = closestNum;
|
||||||
break;
|
break;
|
||||||
|
@ -5280,17 +5287,14 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
||||||
|
|
||||||
if (!foundgoop)
|
if (!foundgoop)
|
||||||
{
|
{
|
||||||
if (mobj->z > 1056*FRACUNIT)
|
// Don't jump to the center when health is low.
|
||||||
waypointNum = 0;
|
// Force the player to beat you with missiles.
|
||||||
else
|
if (mobj->z <= 1056*FRACUNIT || mobj->health <= mobj->info->damage)
|
||||||
waypointNum = 1 + P_RandomKey(4);
|
waypointNum = 1 + P_RandomKey(4);
|
||||||
|
else
|
||||||
|
waypointNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't jump to the center when health is low.
|
|
||||||
// Force the player to beat you with missiles.
|
|
||||||
if (mobj->health <= mobj->info->damage && waypointNum == 0)
|
|
||||||
waypointNum = 1 + P_RandomKey(4);
|
|
||||||
|
|
||||||
if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT
|
if (mobj->tracer && mobj->tracer->type == MT_BOSS3WAYPOINT
|
||||||
&& mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum)
|
&& mobj->tracer->spawnpoint && (mobj->tracer->spawnpoint->options & 7) == waypointNum)
|
||||||
{
|
{
|
||||||
|
@ -5299,15 +5303,12 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
||||||
else
|
else
|
||||||
waypointNum--;
|
waypointNum--;
|
||||||
|
|
||||||
waypointNum %= 5;
|
if (mobj->health <= mobj->info->damage)
|
||||||
|
waypointNum = ((waypointNum + 3) % 4) + 1; // plus four to avoid modulo being negative, minus one to avoid waypoint #0
|
||||||
if (waypointNum < 0)
|
else
|
||||||
waypointNum = 0;
|
waypointNum = ((waypointNum + 5) % 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waypointNum == 0 && mobj->health <= mobj->info->damage)
|
|
||||||
waypointNum = 1 + (P_RandomFixed() & 1);
|
|
||||||
|
|
||||||
// scan the thinkers to find
|
// scan the thinkers to find
|
||||||
// the waypoint to use
|
// the waypoint to use
|
||||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||||
|
@ -5316,11 +5317,17 @@ static void P_Boss7Thinker(mobj_t *mobj)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mo2 = (mobj_t *)th;
|
mo2 = (mobj_t *)th;
|
||||||
if (mo2->type == MT_BOSS3WAYPOINT && mo2->spawnpoint && (mo2->spawnpoint->options & 7) == waypointNum)
|
if (mo2->type != MT_BOSS3WAYPOINT)
|
||||||
{
|
continue;
|
||||||
hitspot = mo2;
|
if (!mo2->spawnpoint)
|
||||||
break;
|
continue;
|
||||||
}
|
if ((mo2->spawnpoint->options & 7) != waypointNum)
|
||||||
|
continue;
|
||||||
|
if (mo2->spawnpoint->extrainfo != extrainfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hitspot = mo2;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hitspot == NULL)
|
if (hitspot == NULL)
|
||||||
|
@ -7667,6 +7674,9 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
else if (mobj->flags & MF_BOSS)
|
else if (mobj->flags & MF_BOSS)
|
||||||
{
|
{
|
||||||
|
if (mobj->spawnpoint && (mobj->spawnpoint->extrainfo < 16) && (bossdisabled & (1<<mobj->spawnpoint->extrainfo)))
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUAh_BossThinker(mobj))
|
if (LUAh_BossThinker(mobj))
|
||||||
{
|
{
|
||||||
|
|
|
@ -470,4 +470,5 @@ extern INT32 numhuntemeralds;
|
||||||
extern boolean runemeraldmanager;
|
extern boolean runemeraldmanager;
|
||||||
extern UINT16 emeraldspawndelay;
|
extern UINT16 emeraldspawndelay;
|
||||||
extern INT32 numstarposts;
|
extern INT32 numstarposts;
|
||||||
|
extern UINT16 bossdisabled;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3990,6 +3990,7 @@ static void P_NetArchiveMisc(void)
|
||||||
WRITEUINT32(save_p, leveltime);
|
WRITEUINT32(save_p, leveltime);
|
||||||
WRITEUINT32(save_p, ssspheres);
|
WRITEUINT32(save_p, ssspheres);
|
||||||
WRITEINT16(save_p, lastmap);
|
WRITEINT16(save_p, lastmap);
|
||||||
|
WRITEUINT16(save_p, bossdisabled);
|
||||||
|
|
||||||
WRITEUINT16(save_p, emeralds);
|
WRITEUINT16(save_p, emeralds);
|
||||||
WRITEUINT8(save_p, stagefailed);
|
WRITEUINT8(save_p, stagefailed);
|
||||||
|
@ -4067,6 +4068,7 @@ static inline boolean P_NetUnArchiveMisc(void)
|
||||||
leveltime = READUINT32(save_p);
|
leveltime = READUINT32(save_p);
|
||||||
ssspheres = READUINT32(save_p);
|
ssspheres = READUINT32(save_p);
|
||||||
lastmap = READINT16(save_p);
|
lastmap = READINT16(save_p);
|
||||||
|
bossdisabled = READUINT16(save_p);
|
||||||
|
|
||||||
emeralds = READUINT16(save_p);
|
emeralds = READUINT16(save_p);
|
||||||
stagefailed = READUINT8(save_p);
|
stagefailed = READUINT8(save_p);
|
||||||
|
|
|
@ -102,6 +102,7 @@ line_t *lines;
|
||||||
side_t *sides;
|
side_t *sides;
|
||||||
mapthing_t *mapthings;
|
mapthing_t *mapthings;
|
||||||
INT32 numstarposts;
|
INT32 numstarposts;
|
||||||
|
UINT16 bossdisabled;
|
||||||
boolean levelloading;
|
boolean levelloading;
|
||||||
UINT8 levelfadecol;
|
UINT8 levelfadecol;
|
||||||
|
|
||||||
|
|
48
src/p_spec.c
48
src/p_spec.c
|
@ -3554,6 +3554,29 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 449: // Enable bosses with parameter
|
||||||
|
{
|
||||||
|
INT32 bossid = sides[line->sidenum[0]].textureoffset>>FRACBITS;
|
||||||
|
if (bossid & ~15) // if any bits other than first 16 are set
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING,
|
||||||
|
M_GetText("Boss enable linedef (tag %d) has an invalid texture x offset.\nConsider changing it or removing it entirely.\n"),
|
||||||
|
line->tag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (line->flags & ML_NOCLIMB)
|
||||||
|
{
|
||||||
|
bossdisabled |= (1<<bossid);
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "Line type 449 Executor: bossid disabled = %d", bossid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bossdisabled &= ~(1<<bossid);
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "Line type 449 Executor: bossid enabled = %d", bossid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 450: // Execute Linedef Executor - for recursion
|
case 450: // Execute Linedef Executor - for recursion
|
||||||
P_LinedefExecute(line->tag, mo, NULL);
|
P_LinedefExecute(line->tag, mo, NULL);
|
||||||
break;
|
break;
|
||||||
|
@ -6399,7 +6422,10 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
|
|
||||||
// This used to be used, and *should* be used in the future,
|
// This used to be used, and *should* be used in the future,
|
||||||
// but currently isn't.
|
// but currently isn't.
|
||||||
(void)fromnetsave;
|
//(void)fromnetsave; -- hooray, it's used!
|
||||||
|
|
||||||
|
if (!fromnetsave)
|
||||||
|
bossdisabled = 0;
|
||||||
|
|
||||||
// Init special SECTORs.
|
// Init special SECTORs.
|
||||||
sector = sectors;
|
sector = sectors;
|
||||||
|
@ -7289,6 +7315,26 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
case 431:
|
case 431:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 449: // Enable bosses with parameter
|
||||||
|
{
|
||||||
|
INT32 bossid = sides[*lines[i].sidenum].textureoffset>>FRACBITS;
|
||||||
|
if (bossid & ~15) // if any bits other than first 16 are set
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING,
|
||||||
|
M_GetText("Boss enable linedef (tag %d) has an invalid texture x offset.\nConsider changing it or removing it entirely.\n"),
|
||||||
|
lines[i].tag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fromnetsave)
|
||||||
|
break;
|
||||||
|
if (!(lines[i].flags & ML_NOCLIMB))
|
||||||
|
{
|
||||||
|
bossdisabled |= (1<<bossid); // gotta disable in the first place to enable
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "Line type 449 spawn effect: bossid disabled = %d", bossid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// 500 is used for a scroller
|
// 500 is used for a scroller
|
||||||
// 501 is used for a scroller
|
// 501 is used for a scroller
|
||||||
// 502 is used for a scroller
|
// 502 is used for a scroller
|
||||||
|
|
Loading…
Reference in a new issue