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_SpawnFreshCopy();
void A_FlickySpawn();
void A_FlickyCenter();
void A_FlickyAim();
void A_FlickyFly();
void A_FlickySoar();

View File

@ -243,6 +243,7 @@ void A_BrakLobShot(mobj_t *actor);
void A_NapalmScatter(mobj_t *actor);
void A_SpawnFreshCopy(mobj_t *actor);
void A_FlickySpawn(mobj_t *actor);
void A_FlickyCenter(mobj_t *actor);
void A_FlickyAim(mobj_t *actor);
void A_FlickyFly(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);
}
// 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.
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)
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;
else
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
// 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)
{
INT32 locvar1 = var1;
@ -10920,6 +11026,8 @@ void A_FlickyFly(mobj_t *actor)
// var1 = how fast to fly
// 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)
{
INT32 locvar1 = var1;
@ -11040,9 +11148,12 @@ void A_FlickyCheck(mobj_t *actor)
if (LUA_CallAction("A_FlickyCheck", actor))
return;
#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->flags |= MF_NOGRAVITY;
@ -11075,9 +11186,12 @@ void A_FlickyHeightCheck(mobj_t *actor)
if (LUA_CallAction("A_FlickyHeightCheck", actor))
return;
#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->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);
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_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);

View File

@ -7089,32 +7089,33 @@ void P_MobjThinker(mobj_t *mobj)
S_StartSound(flame, sfx_fire);
}
break;
case MT_FLICKY_01:
case MT_FLICKY_02:
case MT_FLICKY_03:
case MT_FLICKY_04:
case MT_FLICKY_05:
case MT_FLICKY_06:
case MT_FLICKY_07:
case MT_FLICKY_08:
case MT_FLICKY_09:
case MT_FLICKY_10:
case MT_FLICKY_11:
case MT_FLICKY_12:
case MT_FLICKY_13:
case MT_FLICKY_14:
case MT_FLICKY_15:
case MT_FLICKY_16:
case MT_SECRETFLICKY_01:
case MT_SECRETFLICKY_02:
if (mobj->spawnpoint
case MT_FLICKY_01_CENTER:
case MT_FLICKY_02_CENTER:
case MT_FLICKY_03_CENTER:
case MT_FLICKY_04_CENTER:
case MT_FLICKY_05_CENTER:
case MT_FLICKY_06_CENTER:
case MT_FLICKY_07_CENTER:
case MT_FLICKY_08_CENTER:
case MT_FLICKY_09_CENTER:
case MT_FLICKY_10_CENTER:
case MT_FLICKY_11_CENTER:
case MT_FLICKY_12_CENTER:
case MT_FLICKY_13_CENTER:
case MT_FLICKY_14_CENTER:
case MT_FLICKY_15_CENTER:
case MT_FLICKY_16_CENTER:
case MT_SECRETFLICKY_01_CENTER:
case MT_SECRETFLICKY_02_CENTER:
if (mobj->tracer
&& mobj->spawnpoint
&& (mobj->spawnpoint->options & MTF_AMBUSH)
&& !(mobj->spawnpoint->options & MTF_OBJECTSPECIAL))
{
if (!(mobj->flags2 & MF2_OBJECTFLIP) && mobj->z <= mobj->floorz)
mobj->momz = 7*FRACUNIT;
else if ((mobj->flags2 & MF2_OBJECTFLIP) && mobj->z >= mobj->ceilingz - mobj->height)
mobj->momz = -7*FRACUNIT;
if (!(mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z <= mobj->tracer->floorz)
mobj->tracer->momz = 7*FRACUNIT;
else if ((mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z >= mobj->tracer->ceilingz - mobj->tracer->height)
mobj->tracer->momz = -7*FRACUNIT;
}
break;
case MT_SEED:
@ -10435,38 +10436,6 @@ ML_EFFECT4 : Don't clip inside the ground
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:
{
fixed_t radius, speed;