From 5eafebe4d46733393c35f7b7c19839d2c7ca8f37 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 9 Aug 2018 13:35:36 -0400 Subject: [PATCH] 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~~ --- src/info.h | 1 + src/p_enemy.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/p_local.h | 1 + src/p_mobj.c | 79 ++++++++++---------------------- 4 files changed, 145 insertions(+), 60 deletions(-) diff --git a/src/info.h b/src/info.h index 183e0218a..49c35deb8 100644 --- a/src/info.h +++ b/src/info.h @@ -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(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 6eadefb9c..7eca785e0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -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; diff --git a/src/p_local.h b/src/p_local.h index 682fb7b55..d2537aa37 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -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); diff --git a/src/p_mobj.c b/src/p_mobj.c index 1261091da..b071470dd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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;