A_FlickyCenter implementation - now Flickies can be attracted to players!

* Changed default movement to attraction, vs. aimless
* Flickies spawned from this will always have the FLICKY_CENTER mobj as its target
    * Use P_IsFlickyCenter to identify FLICKY_CENTER mobjs versus players
* FLICKY_CENTER mobj tracer points to the spawned Flicky
* Thanks toaster for the original code~~
This commit is contained in:
mazmazz 2018-08-09 13:35:36 -04:00
parent 38eae01400
commit 5eafebe4d4
4 changed files with 145 additions and 60 deletions

View File

@ -216,6 +216,7 @@ void A_BrakLobShot();
void A_NapalmScatter(); void A_NapalmScatter();
void A_SpawnFreshCopy(); void A_SpawnFreshCopy();
void A_FlickySpawn(); void A_FlickySpawn();
void A_FlickyCenter();
void A_FlickyAim(); void A_FlickyAim();
void A_FlickyFly(); void A_FlickyFly();
void A_FlickySoar(); void A_FlickySoar();

View File

@ -243,6 +243,7 @@ void A_BrakLobShot(mobj_t *actor);
void A_NapalmScatter(mobj_t *actor); void A_NapalmScatter(mobj_t *actor);
void A_SpawnFreshCopy(mobj_t *actor); void A_SpawnFreshCopy(mobj_t *actor);
void A_FlickySpawn(mobj_t *actor); void A_FlickySpawn(mobj_t *actor);
void A_FlickyCenter(mobj_t *actor);
void A_FlickyAim(mobj_t *actor); void A_FlickyAim(mobj_t *actor);
void A_FlickyFly(mobj_t *actor); void A_FlickyFly(mobj_t *actor);
void A_FlickySoar(mobj_t *actor); void A_FlickySoar(mobj_t *actor);
@ -10774,6 +10775,105 @@ void A_FlickySpawn(mobj_t *actor)
P_InternalFlickySpawn(actor, locvar1, ((locvar2) ? locvar2 : 8*FRACUNIT), true); P_InternalFlickySpawn(actor, locvar1, ((locvar2) ? locvar2 : 8*FRACUNIT), true);
} }
// Internal Flicky color setting
void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo)
{
UINT8 flickycolors[] = {
SKINCOLOR_RED,
SKINCOLOR_CYAN,
SKINCOLOR_BLUE,
SKINCOLOR_VAPOR,
SKINCOLOR_PURPLE,
SKINCOLOR_BUBBLEGUM,
SKINCOLOR_NEON,
SKINCOLOR_BLACK,
SKINCOLOR_BEIGE,
SKINCOLOR_LAVENDER,
SKINCOLOR_RUBY,
SKINCOLOR_SALMON,
SKINCOLOR_SUNSET,
SKINCOLOR_ORANGE,
SKINCOLOR_YELLOW,
};
if (extrainfo == 0)
actor->color = flickycolors[P_RandomKey(sizeof(flickycolors))];
else if (extrainfo-1 < sizeof(flickycolors))
actor->color = flickycolors[extrainfo-1];
}
// Function: A_FlickyCenter
//
// Description: Place flickies in-level.
//
// var1 = if 0, spawns random flicky based on level header. Else, spawns the designated thing type.
// var2 = maximum default distance away from spawn the flickies are allowed to travel. If angle != 0, then that's the radius.
//
// If MTF_EXTRA is flagged, Flickies move independently of a target. Else, move around the target.
// If MTF_OBJECTSPECIAL and NOT MTF_EXTRA are flagged, Angle sign determines direction of circular movement.
// If MTF_AMBUSH is flagged, Flickies hop in-place.
// If MTF_AMBUSH and MTF_OBJECTSPECIAL is flagged, Flickies stand in-place without gravity.
//
void A_FlickyCenter(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_FlickyCenter", actor))
return;
#endif
if (!actor->tracer)
{
if (actor->spawnpoint && (actor->spawnpoint->options & MTF_EXTRA))
{
actor->tracer = P_InternalFlickySpawn(actor, locvar1, 1, false);
P_SetTarget(&actor->tracer->target, actor);
actor->tracer->fuse = 0; // < 2*TICRATE means move aimlessly.
if (!(actor->spawnpoint->options & MTF_AMBUSH))
actor->tracer->angle = P_RandomKey(180)*ANG2;
}
else
{
actor->tracer = P_InternalFlickySpawn(actor, locvar1, 1, false);
P_SetTarget(&actor->tracer->target, actor);
actor->tracer->fuse = FRACUNIT;
if (actor->spawnpoint
&& (actor->spawnpoint->options & MTF_OBJECTSPECIAL)
&& !(actor->spawnpoint->options & MTF_EXTRA))
actor->tracer->movedir = actor->spawnpoint->angle >= 0 ? 1 : -1;
}
if (locvar1 == MT_FLICKY_08 && actor->spawnpoint)
P_InternalFlickySetColor(actor->tracer, actor->spawnpoint->extrainfo);
actor->extravalue1 = 0;
}
if (actor->spawnpoint && !(actor->spawnpoint->options & MTF_EXTRA) && !(actor->spawnpoint->options & MTF_AMBUSH))
{
actor->tracer->fuse = FRACUNIT;
if (actor->spawnpoint->angle)
locvar2 = abs(actor->spawnpoint->angle)*FRACUNIT;
P_LookForPlayers(actor, true, false, locvar2);
if (actor->target && P_AproxDistance(actor->target->x - actor->spawnpoint->x*FRACUNIT, actor->target->y - actor->spawnpoint->y*FRACUNIT) < locvar2)
{
actor->extravalue1 = 1;
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z);
}
else if(actor->extravalue1)
{
actor->extravalue1 = 0;
P_TeleportMove(actor, actor->spawnpoint->x*FRACUNIT, actor->spawnpoint->y*FRACUNIT, actor->spawnpoint->z*FRACUNIT);
}
}
}
// Internal Flicky bubbling function. // Internal Flicky bubbling function.
void P_InternalFlickyBubble(mobj_t *actor) void P_InternalFlickyBubble(mobj_t *actor)
{ {
@ -10884,7 +10984,11 @@ void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fi
if (actor->target && abs(chasez - actor->z) > targetdist) if (actor->target && abs(chasez - actor->z) > targetdist)
targetdist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); targetdist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y);
if (actor->spawnpoint && (actor->spawnpoint->options & MTF_OBJECTSPECIAL)) if (actor->target
&& P_IsFlickyCenter(actor->target->type)
&& actor->target->spawnpoint
&& (actor->target->spawnpoint->options & MTF_OBJECTSPECIAL)
&& (actor->target->spawnpoint->options & MTF_EXTRA))
vertangle = 0; vertangle = 0;
else else
vertangle = (R_PointToAngle2(0, actor->z, targetdist, chasez) >> ANGLETOFINESHIFT) & FINEMASK; vertangle = (R_PointToAngle2(0, actor->z, targetdist, chasez) >> ANGLETOFINESHIFT) & FINEMASK;
@ -10900,6 +11004,8 @@ void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fi
// var1 = how fast to fly // var1 = how fast to fly
// var2 = how far ahead the target should be considered // var2 = how far ahead the target should be considered
// //
// If MTF_EXTRA and MTF_OBJECTSPECIAL are flagged, Flicky will always fly at same Z height.
//
void A_FlickyFly(mobj_t *actor) void A_FlickyFly(mobj_t *actor)
{ {
INT32 locvar1 = var1; INT32 locvar1 = var1;
@ -10920,6 +11026,8 @@ void A_FlickyFly(mobj_t *actor)
// var1 = how fast to fly // var1 = how fast to fly
// var2 = how far ahead the target should be considered // var2 = how far ahead the target should be considered
// //
// If MTF_EXTRA and MTF_OBJECTSPECIAL are flagged, Flicky will always fly at same Z height.
//
void A_FlickySoar(mobj_t *actor) void A_FlickySoar(mobj_t *actor)
{ {
INT32 locvar1 = var1; INT32 locvar1 = var1;
@ -11040,9 +11148,12 @@ void A_FlickyCheck(mobj_t *actor)
if (LUA_CallAction("A_FlickyCheck", actor)) if (LUA_CallAction("A_FlickyCheck", actor))
return; return;
#endif #endif
if (actor->spawnpoint && (actor->spawnpoint->options & MTF_AMBUSH)) if (actor->target
&& P_IsFlickyCenter(actor->target->type)
&& actor->target->spawnpoint
&& (actor->target->spawnpoint->options & MTF_AMBUSH))
{ {
if (actor->spawnpoint->options & MTF_OBJECTSPECIAL) if (actor->target->spawnpoint->options & MTF_OBJECTSPECIAL)
{ {
actor->momz = 0; actor->momz = 0;
actor->flags |= MF_NOGRAVITY; actor->flags |= MF_NOGRAVITY;
@ -11075,9 +11186,12 @@ void A_FlickyHeightCheck(mobj_t *actor)
if (LUA_CallAction("A_FlickyHeightCheck", actor)) if (LUA_CallAction("A_FlickyHeightCheck", actor))
return; return;
#endif #endif
if (actor->spawnpoint && (actor->spawnpoint->options & MTF_AMBUSH)) if (actor->target
&& P_IsFlickyCenter(actor->target->type)
&& actor->target->spawnpoint
&& (actor->target->spawnpoint->options & MTF_AMBUSH))
{ {
if (actor->spawnpoint->options & MTF_OBJECTSPECIAL) if (actor->target->spawnpoint->options & MTF_OBJECTSPECIAL)
{ {
actor->momz = 0; actor->momz = 0;
actor->flags |= MF_NOGRAVITY; actor->flags |= MF_NOGRAVITY;

View File

@ -311,6 +311,7 @@ void P_NewChaseDir(mobj_t *actor);
boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist); boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist);
mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers); mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers);
#define P_IsFlickyCenter(type) (type > MT_FLICKY_01 && type < MT_SEED && (type - MT_FLICKY_01) % 2 ? 1 : 0)
void P_InternalFlickyBubble(mobj_t *actor); void P_InternalFlickyBubble(mobj_t *actor);
void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez); void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez);
void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle); void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle);

View File

@ -7089,32 +7089,33 @@ void P_MobjThinker(mobj_t *mobj)
S_StartSound(flame, sfx_fire); S_StartSound(flame, sfx_fire);
} }
break; break;
case MT_FLICKY_01: case MT_FLICKY_01_CENTER:
case MT_FLICKY_02: case MT_FLICKY_02_CENTER:
case MT_FLICKY_03: case MT_FLICKY_03_CENTER:
case MT_FLICKY_04: case MT_FLICKY_04_CENTER:
case MT_FLICKY_05: case MT_FLICKY_05_CENTER:
case MT_FLICKY_06: case MT_FLICKY_06_CENTER:
case MT_FLICKY_07: case MT_FLICKY_07_CENTER:
case MT_FLICKY_08: case MT_FLICKY_08_CENTER:
case MT_FLICKY_09: case MT_FLICKY_09_CENTER:
case MT_FLICKY_10: case MT_FLICKY_10_CENTER:
case MT_FLICKY_11: case MT_FLICKY_11_CENTER:
case MT_FLICKY_12: case MT_FLICKY_12_CENTER:
case MT_FLICKY_13: case MT_FLICKY_13_CENTER:
case MT_FLICKY_14: case MT_FLICKY_14_CENTER:
case MT_FLICKY_15: case MT_FLICKY_15_CENTER:
case MT_FLICKY_16: case MT_FLICKY_16_CENTER:
case MT_SECRETFLICKY_01: case MT_SECRETFLICKY_01_CENTER:
case MT_SECRETFLICKY_02: case MT_SECRETFLICKY_02_CENTER:
if (mobj->spawnpoint if (mobj->tracer
&& mobj->spawnpoint
&& (mobj->spawnpoint->options & MTF_AMBUSH) && (mobj->spawnpoint->options & MTF_AMBUSH)
&& !(mobj->spawnpoint->options & MTF_OBJECTSPECIAL)) && !(mobj->spawnpoint->options & MTF_OBJECTSPECIAL))
{ {
if (!(mobj->flags2 & MF2_OBJECTFLIP) && mobj->z <= mobj->floorz) if (!(mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z <= mobj->tracer->floorz)
mobj->momz = 7*FRACUNIT; mobj->tracer->momz = 7*FRACUNIT;
else if ((mobj->flags2 & MF2_OBJECTFLIP) && mobj->z >= mobj->ceilingz - mobj->height) else if ((mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z >= mobj->tracer->ceilingz - mobj->tracer->height)
mobj->momz = -7*FRACUNIT; mobj->tracer->momz = -7*FRACUNIT;
} }
break; break;
case MT_SEED: case MT_SEED:
@ -10435,38 +10436,6 @@ ML_EFFECT4 : Don't clip inside the ground
break; break;
} }
case MT_FLICKY_08:
if (mthing->extrainfo == 1)
mobj->color = SKINCOLOR_RED;
else if (mthing->extrainfo == 2)
mobj->color = SKINCOLOR_CYAN;
else if (mthing->extrainfo == 3)
mobj->color = SKINCOLOR_BLUE;
else if (mthing->extrainfo == 4)
mobj->color = SKINCOLOR_VAPOR;
else if (mthing->extrainfo == 5)
mobj->color = SKINCOLOR_PURPLE;
else if (mthing->extrainfo == 6)
mobj->color = SKINCOLOR_BUBBLEGUM;
else if (mthing->extrainfo == 7)
mobj->color = SKINCOLOR_NEON;
else if (mthing->extrainfo == 8)
mobj->color = SKINCOLOR_BLACK;
else if (mthing->extrainfo == 9)
mobj->color = SKINCOLOR_BEIGE;
else if (mthing->extrainfo == 10)
mobj->color = SKINCOLOR_LAVENDER;
else if (mthing->extrainfo == 11)
mobj->color = SKINCOLOR_RUBY;
else if (mthing->extrainfo == 12)
mobj->color = SKINCOLOR_SALMON;
else if (mthing->extrainfo == 13)
mobj->color = SKINCOLOR_SUNSET;
else if (mthing->extrainfo == 14)
mobj->color = SKINCOLOR_ORANGE;
else if (mthing->extrainfo == 15)
mobj->color = SKINCOLOR_YELLOW;
break;
case MT_PARTICLEGEN: case MT_PARTICLEGEN:
{ {
fixed_t radius, speed; fixed_t radius, speed;