From 4e319541b69e4a3cb9be22efe474a2248d51f5da Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 18:24:31 -0400 Subject: [PATCH 01/26] Nights Drone mobj and state entries * New entries: NIGHTSDRONE_MAN, NIGHTSDRONE_SPARKLING * NIGHTSGOAL renamed to NIGHTSDRONE_GOAL * MT_NIGHTSDRONE repurposed as an invisble, no-gravity hitbox --- src/dehacked.c | 16 ++++++----- src/info.c | 74 +++++++++++++++++++++++++++++++++++++++++++------- src/info.h | 16 ++++++----- src/p_mobj.c | 4 +-- 4 files changed, 84 insertions(+), 26 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index fb0f958c3..5c2953a55 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5952,8 +5952,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_TOAD", // Nights-specific stuff - "S_NIGHTSDRONE1", - "S_NIGHTSDRONE2", + "S_NIGHTSDRONE_MAN1", + "S_NIGHTSDRONE_MAN2", "S_NIGHTSDRONE_SPARKLING1", "S_NIGHTSDRONE_SPARKLING2", "S_NIGHTSDRONE_SPARKLING3", @@ -5970,10 +5970,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_NIGHTSDRONE_SPARKLING14", "S_NIGHTSDRONE_SPARKLING15", "S_NIGHTSDRONE_SPARKLING16", - "S_NIGHTSGOAL1", - "S_NIGHTSGOAL2", - "S_NIGHTSGOAL3", - "S_NIGHTSGOAL4", + "S_NIGHTSDRONE_GOAL1", + "S_NIGHTSDRONE_GOAL2", + "S_NIGHTSDRONE_GOAL3", + "S_NIGHTSDRONE_GOAL4", "S_NIGHTSPARKLE1", "S_NIGHTSPARKLE2", @@ -6825,7 +6825,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_AXISTRANSFER", "MT_AXISTRANSFERLINE", "MT_NIGHTSDRONE", - "MT_NIGHTSGOAL", + "MT_NIGHTSDRONE_MAN", + "MT_NIGHTSDRONE_SPARKLING", + "MT_NIGHTSDRONE_GOAL", "MT_NIGHTSPARKLE", "MT_NIGHTSLOOPHELPER", "MT_NIGHTSBUMPER", // NiGHTS Bumper diff --git a/src/info.c b/src/info.c index 782ab6381..00a0342c5 100644 --- a/src/info.c +++ b/src/info.c @@ -3239,8 +3239,8 @@ state_t states[NUMSTATES] = {SPR_TOAD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TOAD // Nights Drone - {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE2}, // S_NIGHTSDRONE1 - {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE1}, // S_NIGHTSDRONE2 + {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE_MAN2}, // S_NIGHTSDRONE_MAN1 + {SPR_NDRN, 0, -1, {NULL}, 0, 0, S_NIGHTSDRONE_MAN1}, // S_NIGHTSDRONE_MAN2 // Sparkling point (RETURN TO THE GOAL, etc) {SPR_IVSP, 0, 1, {A_GhostMe}, 0, 0, S_NIGHTSDRONE_SPARKLING2}, // S_NIGHTSDRONE_SPARKLING1 @@ -3261,10 +3261,10 @@ state_t states[NUMSTATES] = {SPR_IVSP, 30, 1, {A_GhostMe}, 0, 0, S_NIGHTSDRONE_SPARKLING1}, // S_NIGHTSDRONE_SPARKLING16 // NiGHTS GOAL banner (inside the sparkles!) - {SPR_GOAL, 0, 4, {NULL}, 0, 0, S_NIGHTSGOAL2}, // S_NIGHTSGOAL1 - {SPR_GOAL, 1, 4, {NULL}, 0, 0, S_NIGHTSGOAL3}, // S_NIGHTSGOAL2 - {SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSGOAL4}, // S_NIGHTSGOAL3 - {SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSGOAL1}, // S_NIGHTSGOAL4 + {SPR_GOAL, 0, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL2}, // S_NIGHTSDRONE_GOAL1 + {SPR_GOAL, 1, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL3}, // S_NIGHTSDRONE_GOAL2 + {SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL4}, // S_NIGHTSDRONE_GOAL3 + {SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSDRONE_GOAL1}, // S_NIGHTSDRONE_GOAL4 // Nights Sparkle {SPR_NSPK, FF_FULLBRIGHT, 140, {NULL}, 0, 0, S_NIGHTSPARKLE2}, // S_NIGHTSPARKLE1 @@ -16100,7 +16100,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_NIGHTSDRONE 1703, // doomednum - S_NIGHTSDRONE1, // spawnstate + S_INVISIBLE, // spawnstate 120, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -16125,9 +16125,36 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_NIGHTSGOAL + { // MT_NIGHTSDRONE_MAN + -1, // doomednum + S_INVISIBLE, // spawnstate + 120, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NIGHTSDRONE_MAN1, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRONE_SPARKLING -1, // doomednum - S_NIGHTSGOAL1, // spawnstate + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -16136,7 +16163,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // painstate 255, // painchance sfx_None, // painsound - S_NULL, // meleestate + S_NIGHTSDRONE_SPARKLING1, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 56*FRACUNIT, // height + 1, // display offset + 1000, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_NIGHTSDRONE_GOAL + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 255, // painchance + sfx_None, // painsound + S_NIGHTSDRONE_GOAL1, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate diff --git a/src/info.h b/src/info.h index dfd30bc5b..a386b199a 100644 --- a/src/info.h +++ b/src/info.h @@ -3305,8 +3305,8 @@ typedef enum state S_TOAD, // Nights-specific stuff - S_NIGHTSDRONE1, - S_NIGHTSDRONE2, + S_NIGHTSDRONE_MAN1, + S_NIGHTSDRONE_MAN2, S_NIGHTSDRONE_SPARKLING1, S_NIGHTSDRONE_SPARKLING2, S_NIGHTSDRONE_SPARKLING3, @@ -3323,10 +3323,10 @@ typedef enum state S_NIGHTSDRONE_SPARKLING14, S_NIGHTSDRONE_SPARKLING15, S_NIGHTSDRONE_SPARKLING16, - S_NIGHTSGOAL1, - S_NIGHTSGOAL2, - S_NIGHTSGOAL3, - S_NIGHTSGOAL4, + S_NIGHTSDRONE_GOAL1, + S_NIGHTSDRONE_GOAL2, + S_NIGHTSDRONE_GOAL3, + S_NIGHTSDRONE_GOAL4, S_NIGHTSPARKLE1, S_NIGHTSPARKLE2, @@ -4198,7 +4198,9 @@ typedef enum mobj_type MT_AXISTRANSFER, MT_AXISTRANSFERLINE, MT_NIGHTSDRONE, - MT_NIGHTSGOAL, + MT_NIGHTSDRONE_MAN, + MT_NIGHTSDRONE_SPARKLING, + MT_NIGHTSDRONE_GOAL, MT_NIGHTSPARKLE, MT_NIGHTSLOOPHELPER, MT_NIGHTSBUMPER, // NiGHTS Bumper diff --git a/src/p_mobj.c b/src/p_mobj.c index 4353e67c3..af409b8bf 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7848,7 +7848,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->flags &= ~MF_NOGRAVITY; mobj->flags2 |= MF2_DONTDRAW; - P_SetMobjState(mobj, S_NIGHTSDRONE1); + //P_SetMobjState(mobj, S_NIGHTSDRONE); } } // Invisible/bouncing mode. @@ -7880,7 +7880,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->z += (mobj->spawnpoint->options >> ZSHIFT)<target, P_SpawnMobjFromMobj(mobj, 0, 0, FRACUNIT, MT_NIGHTSGOAL)); + P_SetTarget(&mobj->target, P_SpawnMobjFromMobj(mobj, 0, 0, FRACUNIT, MT_NIGHTSDRONE_GOAL)); mobj->flags2 &= ~MF2_DONTDRAW; mobj->flags |= MF_NOGRAVITY; From 60f6792ad06d3b805c0857ee9083e99f79a504c2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 19:25:49 -0400 Subject: [PATCH 02/26] Basic implementation for player position correction to Drone center * player->drone mobj variable * P_MoveNiGHTSToDrone, will change later --- src/d_player.h | 1 + src/lua_playerlib.c | 9 +++++++++ src/p_inter.c | 1 + src/p_saveg.c | 17 +++++++++++++++++ src/p_setup.c | 2 +- src/p_user.c | 21 +++++++++++++++++++++ 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index 7bee5f337..91cafa515 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -455,6 +455,7 @@ typedef struct player_s UINT8 drilldelay; boolean bonustime; // Capsule destroyed, now it's bonus time! mobj_t *capsule; // Go inside the capsule + mobj_t *drone; // Move center to the drone UINT8 mare; // Current mare // Statistical purposes. diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index ff62f2459..4fdf25fad 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -288,6 +288,8 @@ static int player_get(lua_State *L) lua_pushboolean(L, plr->bonustime); else if (fastcmp(field,"capsule")) LUA_PushUserdata(L, plr->capsule, META_MOBJ); + else if (fastcmp(field,"drone")) + LUA_PushUserdata(L, plr->drone, META_MOBJ); else if (fastcmp(field,"mare")) lua_pushinteger(L, plr->mare); else if (fastcmp(field,"marebegunat")) @@ -568,6 +570,13 @@ static int player_set(lua_State *L) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->capsule, mo); } + else if (fastcmp(field,"drone")) + { + mobj_t *mo = NULL; + if (!lua_isnil(L, 3)) + mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&plr->drone, mo); + } else if (fastcmp(field,"mare")) plr->mare = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"marebegunat")) diff --git a/src/p_inter.c b/src/p_inter.c index ce8bba6b6..688dc685d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -794,6 +794,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE)) P_SetTarget(&special->tracer, toucher); P_NightserizePlayer(player, special->health); // Transform! + P_SetTarget(&player->drone, special); // Mark the player as 'center into the drone' if (!spec) { if (toucher->tracer) // Move the ideya over to the drone! diff --git a/src/p_saveg.c b/src/p_saveg.c index 7cf437384..699b57a5c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -57,6 +57,7 @@ typedef enum FIRSTAXIS = 0x10, SECONDAXIS = 0x20, FOLLOW = 0x40, + DRONE = 0x80, } player_saveflags; // @@ -226,6 +227,9 @@ static void P_NetArchivePlayers(void) if (players[i].followmobj) flags |= FOLLOW; + if (players[i].drone) + flags |= DRONE; + WRITEINT16(save_p, players[i].lastsidehit); WRITEINT16(save_p, players[i].lastlinehit); @@ -254,6 +258,9 @@ static void P_NetArchivePlayers(void) if (flags & FOLLOW) WRITEUINT32(save_p, players[i].followmobj->mobjnum); + if (flags & DRONE) + WRITEUINT32(save_p, players[i].drone->mobjnum); + WRITEFIXED(save_p, players[i].camerascale); WRITEFIXED(save_p, players[i].shieldscale); @@ -428,6 +435,9 @@ static void P_NetUnArchivePlayers(void) if (flags & FOLLOW) players[i].followmobj = (mobj_t *)(size_t)READUINT32(save_p); + if (flags & DRONE) + players[i].drone = (mobj_t *)(size_t)READUINT32(save_p); + players[i].camerascale = READFIXED(save_p); players[i].shieldscale = READFIXED(save_p); @@ -3099,6 +3109,13 @@ static void P_RelinkPointers(void) if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type); } + if (mobj->player && mobj->player->drone) + { + temp = (UINT32)(size_t)mobj->player->drone; + mobj->player->drone = NULL; + if (!P_SetTarget(&mobj->player->drone, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "drone not found on %d\n", mobj->type); + } } } } diff --git a/src/p_setup.c b/src/p_setup.c index c62f281b3..7e8d0fdb1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2401,7 +2401,7 @@ static void P_LevelInitStuff(void) // unset ALL the pointers. P_SetTarget isn't needed here because if this // function is being called we're just going to clobber the data anyways players[i].mo = players[i].followmobj = players[i].awayviewmobj =\ - players[i].capsule = players[i].axis1 = players[i].axis2 = NULL; + players[i].capsule = players[i].axis1 = players[i].axis2 = players[i].drone = NULL; } } diff --git a/src/p_user.c b/src/p_user.c index fd09b0847..18e8e29ca 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6095,6 +6095,20 @@ static void P_DoNiGHTSCapsule(player_t *player) player->capsule->extravalue1 = -1; } +// +// P_MoveNiGHTSToDrone +// +// Pull NiGHTS to the drone during Nightserizing +// +static void P_MoveNiGHTSToDrone(player_t *player) +{ + if (!player->drone) + return; + player->mo->momx = player->mo->momy = player->mo->momz = 0; + P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z); + P_SetTarget(&player->drone, NULL); +} + // // P_NiGHTSMovement // @@ -7007,6 +7021,13 @@ static void P_MovePlayer(player_t *player) return; } + // Suck player into their drone + if (player->drone) + { + P_MoveNiGHTSToDrone(player); + return; + } + // Test revamped NiGHTS movement. if (player->powers[pw_carry] == CR_NIGHTSMODE) { From 30fccd6946318fa158d42489e00180d871074f66 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 22:11:48 -0400 Subject: [PATCH 03/26] Drone de-coupling implementation * Visual elements and hitbox work as expected with scaling and OBJECTFLIP --- src/p_mobj.c | 159 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 59 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index af409b8bf..8b49f140c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7827,78 +7827,102 @@ void P_MobjThinker(mobj_t *mobj) } break; case MT_NIGHTSDRONE: - // GOAL mode? - if (mobj->state >= &states[S_NIGHTSDRONE_SPARKLING1] && mobj->state <= &states[S_NIGHTSDRONE_SPARKLING16]) { - INT32 i; - boolean bonustime = false; + mobj_t *goalpost = NULL; + mobj_t *sparkle = NULL; + mobj_t *droneman = NULL; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) - { - bonustime = true; - break; - } - - if (!bonustime) + if (mobj->target && mobj->target->type == MT_NIGHTSDRONE_GOAL) { - CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); - P_RemoveMobj(mobj->target); - P_SetTarget(&mobj->target, NULL); - - mobj->flags &= ~MF_NOGRAVITY; - mobj->flags2 |= MF2_DONTDRAW; - //P_SetMobjState(mobj, S_NIGHTSDRONE); + goalpost = mobj->target; + if (goalpost->target && goalpost->target->type == MT_NIGHTSDRONE_SPARKLING) + sparkle = goalpost->target; + if (goalpost->tracer && goalpost->tracer->type == MT_NIGHTSDRONE_MAN) + droneman = goalpost->tracer; } - } - // Invisible/bouncing mode. - else - { - INT32 i; - boolean bonustime = false; - // Bouncy bouncy! - mobj->angle += ANG10; - if (mobj->flags2 & MF2_DONTDRAW) - mobj->momz = 0; - else if (mobj->z <= mobj->floorz) - mobj->momz = 5*FRACUNIT; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) - { - bonustime = true; - break; - } - - if (bonustime) + // GOAL mode? + if (sparkle->state >= &states[S_NIGHTSDRONE_SPARKLING1] && sparkle->state <= &states[S_NIGHTSDRONE_SPARKLING16]) { - mobj->z = mobj->floorz + mobj->height; - mobj->angle = mobj->momz = 0; + INT32 i; + boolean bonustime = false; - if (mobj->spawnpoint) - mobj->z += (mobj->spawnpoint->options >> ZSHIFT)<target, P_SpawnMobjFromMobj(mobj, 0, 0, FRACUNIT, MT_NIGHTSDRONE_GOAL)); - - mobj->flags2 &= ~MF2_DONTDRAW; - mobj->flags |= MF_NOGRAVITY; - P_SetMobjState(mobj, S_NIGHTSDRONE_SPARKLING1); - } - else if (!G_IsSpecialStage(gamemap)) - { for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].powers[pw_carry] != CR_NIGHTSMODE) + if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) { - bonustime = true; // variable reuse + bonustime = true; + break; + } + + if (!bonustime) + { + CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); + if (goalpost && goalpost->state != &states[S_INVISIBLE]) + P_SetMobjState(goalpost, S_INVISIBLE); + if (sparkle && sparkle->state != &states[S_INVISIBLE]) + P_SetMobjState(sparkle, S_INVISIBLE); + } + } + // Invisible/bouncing mode. + else + { + INT32 i; + boolean bonustime = false; + + // Bouncy bouncy! + droneman->angle += ANG10; + if (droneman->flags2 & MF2_DONTDRAW) + droneman->momz = 0; + else if (!(droneman->flags2 & MF2_OBJECTFLIP) + && droneman->z <= droneman->floorz) + droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); + else if ((droneman->flags2 & MF2_OBJECTFLIP) + && droneman->z >= droneman->ceilingz - droneman->height) + droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); + + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) + { + bonustime = true; break; } if (bonustime) - mobj->flags2 &= ~MF2_DONTDRAW; - else - mobj->flags2 |= MF2_DONTDRAW; + { + CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); + if (droneman && droneman->state != &states[S_INVISIBLE]) + P_SetMobjState(droneman, S_INVISIBLE); + if (goalpost && goalpost->state == &states[S_INVISIBLE]) + P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); + if (sparkle && sparkle->state == &states[S_INVISIBLE]) + P_SetMobjState(sparkle, mobjinfo[sparkle->type].meleestate); + } + else if (!G_IsSpecialStage(gamemap)) + { + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].powers[pw_carry] != CR_NIGHTSMODE) + { + bonustime = true; // variable reuse + break; + } + + if (bonustime) + { + // show droneman if at least one player is non-nights + if (goalpost && goalpost->state != &states[S_INVISIBLE]) + P_SetMobjState(goalpost, S_INVISIBLE); + if (sparkle && sparkle->state != &states[S_INVISIBLE]) + P_SetMobjState(sparkle, S_INVISIBLE); + if (droneman && droneman->state == &states[S_INVISIBLE]) + P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + } + else + { + // else, hide it + if (droneman && droneman->state != &states[S_INVISIBLE]) + P_SetMobjState(droneman, S_INVISIBLE); + } + } } } break; @@ -10516,6 +10540,23 @@ ML_EFFECT4 : Don't clip inside the ground case MT_NIGHTSDRONE: if (mthing->angle > 0) mobj->health = mthing->angle; + + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + } + + // spawn visual components + { + mobj_t *goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_GOAL); + mobj_t *sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_SPARKLING); + mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_MAN); + + P_SetTarget(&mobj->target, goalpost); + P_SetTarget(&goalpost->target, sparkle); + P_SetTarget(&goalpost->tracer, droneman); + } break; case MT_HIVEELEMENTAL: if (mthing->extrainfo) From 3ec985dde9902bd62c4827276544a0771aaad3ef Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 23:49:02 -0400 Subject: [PATCH 04/26] ORBITEM CENTER states for A_OrbitNights target height offset --- src/dehacked.c | 13 +++++++++++++ src/info.c | 17 +++++++++++++++-- src/info.h | 13 +++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5c2953a55..fd289dc18 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6041,11 +6041,24 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ORBITEM6", "S_ORBITEM7", "S_ORBITEM8", + "S_ORBITEM1_CENTER", + "S_ORBITEM2_CENTER", + "S_ORBITEM3_CENTER", + "S_ORBITEM4_CENTER", + "S_ORBITEM5_CENTER", + "S_ORBITEM6_CENTER", + "S_ORBITEM7_CENTER", + "S_ORBITEM8_CENTER", "S_ORBIDYA1", "S_ORBIDYA2", "S_ORBIDYA3", "S_ORBIDYA4", "S_ORBIDYA5", + "S_ORBIDYA1_CENTER", + "S_ORBIDYA2_CENTER", + "S_ORBIDYA3_CENTER", + "S_ORBIDYA4_CENTER", + "S_ORBIDYA5_CENTER", // "Flicky" helper "S_NIGHTOPIANHELPER1", diff --git a/src/info.c b/src/info.c index 00a0342c5..195b2769b 100644 --- a/src/info.c +++ b/src/info.c @@ -3338,11 +3338,24 @@ state_t states[NUMSTATES] = {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 + {SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM1_CENTER}, // S_ORBITEM1_CENTER + {SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM2_CENTER}, // S_ORBITEM2_CENTER + {SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM3_CENTER}, // S_ORBITEM3_CENTER + {SPR_CEMG, FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM4_CENTER}, // S_ORBITEM4_CENTER + {SPR_CEMG, FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM5_CENTER}, // S_ORBITEM5_CENTER + {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM6_CENTER}, // S_ORBITEM6_CENTER + {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM7_CENTER}, // S_ORBITEM7_CENTER + {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM8_CENTER}, // S_ORBITEM8_CENTER {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA4}, // S_ORBIDYA4 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA5}, // S_ORBIDYA5 + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA1_CENTER}, // S_ORBIDYA1_CENTER + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA2_CENTER}, // S_ORBIDYA2_CENTER + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA3_CENTER}, // S_ORBIDYA3_CENTER + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA4_CENTER}, // S_ORBIDYA4_CENTER + {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA5_CENTER}, // S_ORBIDYA5_CENTER // Flicky helper for NiGHTS {SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER2}, // S_NIGHTOPIANHELPER1 @@ -14618,7 +14631,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_ORBITEM1, // meleestate S_ORBIDYA1, // missilestate S_XPLD1, // deathstate - S_NULL, // xdeathstate + S_ORBITEM1_CENTER, // xdeathstate sfx_s3k8a, // deathsound 8, // speed 8*FRACUNIT, // radius @@ -14628,7 +14641,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags - S_NULL // raisestate + S_ORBIDYA1_CENTER // raisestate }, { // MT_LOCKON diff --git a/src/info.h b/src/info.h index a386b199a..11150a114 100644 --- a/src/info.h +++ b/src/info.h @@ -3394,11 +3394,24 @@ typedef enum state S_ORBITEM6, S_ORBITEM7, S_ORBITEM8, + S_ORBITEM1_CENTER, + S_ORBITEM2_CENTER, + S_ORBITEM3_CENTER, + S_ORBITEM4_CENTER, + S_ORBITEM5_CENTER, + S_ORBITEM6_CENTER, + S_ORBITEM7_CENTER, + S_ORBITEM8_CENTER, S_ORBIDYA1, S_ORBIDYA2, S_ORBIDYA3, S_ORBIDYA4, S_ORBIDYA5, + S_ORBIDYA1_CENTER, + S_ORBIDYA2_CENTER, + S_ORBIDYA3_CENTER, + S_ORBIDYA4_CENTER, + S_ORBIDYA5_CENTER, // "Flicky" helper S_NIGHTOPIANHELPER1, From 2dc74aa1865381e08f742ef27af8e1ea37edfbe2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 10 Aug 2018 23:50:23 -0400 Subject: [PATCH 05/26] A_OrbitNights height offset by target height implementation --- src/p_enemy.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 9235a1d0f..40adb9d4a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8542,12 +8542,16 @@ void A_ToggleFlameJet(mobj_t* actor) // Description: Used by Chaos Emeralds to orbit around Nights (aka Super Sonic.) // // var1 = Angle adjustment (aka orbit speed) -// var2 = Lower four bits: height offset, Upper 4 bits = set if object is Nightopian Helper +// var2: +// Lower 16 bits: height offset +// Upper 8 bits: set if object is Nightopian Helper +// Highest 8 bits: center height offset to target by this divisor // void A_OrbitNights(mobj_t* actor) { INT32 ofs = (var2 & 0xFFFF); - boolean ishelper = (var2 & 0xFFFF0000); + boolean ishelper = ((var2 >> 16) & 0xFF); + INT32 ofsdiv = var2 >> 24; #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; @@ -8577,7 +8581,10 @@ void A_OrbitNights(mobj_t* actor) actor->x = actor->target->x + fc; actor->y = actor->target->y + fs; - actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); + if (ofsdiv) + actor->z = (actor->target->z + actor->target->height / ofsdiv) + fh + FixedMul(16*FRACUNIT, actor->scale); + else + actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); // Semi-lazy hack actor->angle = (angle_t)actor->extravalue1 + ANGLE_90; @@ -11636,4 +11643,4 @@ void A_CheckFlags2(mobj_t *actor) if (actor->flags2 & locvar1) P_SetMobjState(actor, (statenum_t)locvar2); -} \ No newline at end of file +} From 6f1b9de43689030f7b6b096a387f8aa4f02c42b1 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 00:09:02 -0400 Subject: [PATCH 06/26] Switch Ideya orbiting state to centered offset states when orbiting around Drone --- src/p_inter.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 688dc685d..f10d680dd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -799,10 +799,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { if (toucher->tracer) // Move the ideya over to the drone! { + statenum_t currentstate = toucher->tracer->state - states; mobj_t *hnext = special->hnext; P_SetTarget(&special->hnext, toucher->tracer); P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. P_SetTarget(&special->hnext->target, special); + + // switch to centered orbit states + if (currentstate >= mobjinfo[MT_GOTEMERALD].missilestate + && currentstate <= mobjinfo[MT_GOTEMERALD].missilestate + 4) + P_SetMobjState(toucher->tracer, + mobjinfo[MT_GOTEMERALD].raisestate + currentstate - mobjinfo[MT_GOTEMERALD].missilestate); + P_SetTarget(&toucher->tracer, NULL); if (hnext) { @@ -814,8 +822,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->exiting) // ...then move it back? { mobj_t *hnext = special; + statenum_t currentstate; while ((hnext = hnext->hnext)) + { P_SetTarget(&hnext->target, toucher); + currentstate = hnext->state - states; + + // switch to regular orbit states + if (currentstate >= mobjinfo[MT_GOTEMERALD].raisestate + && currentstate <= mobjinfo[MT_GOTEMERALD].raisestate + 4) + P_SetMobjState(hnext, + mobjinfo[MT_GOTEMERALD].missilestate + currentstate - mobjinfo[MT_GOTEMERALD].raisestate); + } } return; } From c5d6dd55d53526283f787d61d024d3023fe651b1 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 00:49:28 -0400 Subject: [PATCH 07/26] player->oldscale var for pre-Nightserize scale --- src/d_player.h | 1 + src/lua_playerlib.c | 4 ++++ src/p_saveg.c | 2 ++ src/p_setup.c | 4 ++-- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 91cafa515..9a7ddc089 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -457,6 +457,7 @@ typedef struct player_s mobj_t *capsule; // Go inside the capsule mobj_t *drone; // Move center to the drone UINT8 mare; // Current mare + fixed_t oldscale; // Pre-Nightserize scale // Statistical purposes. tic_t marebegunat; // Leveltime when mare begun diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 4fdf25fad..4a5c690b0 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -292,6 +292,8 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->drone, META_MOBJ); else if (fastcmp(field,"mare")) lua_pushinteger(L, plr->mare); + else if (fastcmp(field,"oldscale")) + lua_pushfixed(L, plr->oldscale); else if (fastcmp(field,"marebegunat")) lua_pushinteger(L, plr->marebegunat); else if (fastcmp(field,"startedtime")) @@ -579,6 +581,8 @@ static int player_set(lua_State *L) } else if (fastcmp(field,"mare")) plr->mare = (UINT8)luaL_checkinteger(L, 3); + else if (fastcmp(field,"oldscale")) + plr->oldscale = luaL_checkfixed(L, 3); else if (fastcmp(field,"marebegunat")) plr->marebegunat = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"startedtime")) diff --git a/src/p_saveg.c b/src/p_saveg.c index 699b57a5c..923f0b2ed 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -199,6 +199,7 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].drilldelay); WRITEUINT8(save_p, players[i].bonustime); WRITEUINT8(save_p, players[i].mare); + WRITEFIXED(save_p, players[i].oldscale); WRITEUINT32(save_p, players[i].marebegunat); WRITEUINT32(save_p, players[i].startedtime); @@ -394,6 +395,7 @@ static void P_NetUnArchivePlayers(void) players[i].drilldelay = READUINT8(save_p); players[i].bonustime = (boolean)READUINT8(save_p); players[i].mare = READUINT8(save_p); + players[i].oldscale = READFIXED(save_p); players[i].marebegunat = READUINT32(save_p); players[i].startedtime = READUINT32(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 7e8d0fdb1..b154789ab 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2385,8 +2385,8 @@ static void P_LevelInitStuff(void) players[i].texttimer = players[i].linkcount =\ players[i].linktimer = players[i].flyangle =\ players[i].anotherflyangle = players[i].nightstime =\ - players[i].mare = players[i].realtime =\ - players[i].exiting = 0; + players[i].mare = players[i].oldscale =\ + players[i].realtime = players[i].exiting = 0; // i guess this could be part of the above but i feel mildly uncomfortable implicitly casting players[i].gotcontinue = false; From 46f1463595e0184ad76cfd2c808415eccb49bbdf Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 00:51:33 -0400 Subject: [PATCH 08/26] Scale player to Drone's scale on Nightserize, and reset scale on De-Nightserize * Also correct player's position to Z center of Drone hitbox on Nightserize --- src/p_inter.c | 2 +- src/p_user.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index f10d680dd..99b43dbfd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -793,8 +793,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SwitchSpheresBonusMode(false); if (!(netgame || multiplayer) && !(player->powers[pw_carry] == CR_NIGHTSMODE)) P_SetTarget(&special->tracer, toucher); - P_NightserizePlayer(player, special->health); // Transform! P_SetTarget(&player->drone, special); // Mark the player as 'center into the drone' + P_NightserizePlayer(player, special->health); // Transform! if (!spec) { if (toucher->tracer) // Move the ideya over to the drone! diff --git a/src/p_user.c b/src/p_user.c index 18e8e29ca..22ac51df1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -623,6 +623,10 @@ static void P_DeNightserizePlayer(player_t *player) break; } + if (player->mo->scale != player->oldscale) + player->mo->destscale = player->oldscale; + player->oldscale = 0; + // Restore from drowning music P_RestoreMusic(player); } @@ -640,7 +644,10 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) return; if (player->powers[pw_carry] != CR_NIGHTSMODE) + { player->mo->height = P_GetPlayerHeight(player); // Just to make sure jumping into the drone doesn't result in a squashed hitbox. + player->oldscale = player->mo->scale; + } player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING); player->homing = 0; @@ -765,6 +772,9 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->texttimer = (UINT8)(110 - timeinmap); } + if (player->drone && player->drone->scale != player->mo->scale) + player->mo->destscale = player->drone->scale; + player->powers[pw_carry] = CR_NIGHTSMODE; } @@ -6105,7 +6115,7 @@ static void P_MoveNiGHTSToDrone(player_t *player) if (!player->drone) return; player->mo->momx = player->mo->momy = player->mo->momz = 0; - P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z); + P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z + player->drone->height/2 - player->mo->height/2); P_SetTarget(&player->drone, NULL); } From 3b18d3984eab3c3e45536cc457e189840a360bb1 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 02:03:44 -0400 Subject: [PATCH 09/26] * Bounce Droneman within hitbox instead of floorz * Correct Droneman hiding so he always stays within hitbox even when invisible --- src/info.c | 2 +- src/p_mobj.c | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/info.c b/src/info.c index 195b2769b..38ba0bdf6 100644 --- a/src/info.c +++ b/src/info.c @@ -16134,7 +16134,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // mass 0, // damage sfx_ideya, // activesound - MF_SPECIAL, // flags + MF_NOGRAVITY|MF_SPECIAL, // flags S_NULL // raisestate }, diff --git a/src/p_mobj.c b/src/p_mobj.c index 8b49f140c..8d6382f2f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7871,13 +7871,11 @@ void P_MobjThinker(mobj_t *mobj) // Bouncy bouncy! droneman->angle += ANG10; - if (droneman->flags2 & MF2_DONTDRAW) - droneman->momz = 0; - else if (!(droneman->flags2 & MF2_OBJECTFLIP) - && droneman->z <= droneman->floorz) + if (!(droneman->flags2 & MF2_OBJECTFLIP) + && droneman->z <= mobj->z) droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); else if ((droneman->flags2 & MF2_OBJECTFLIP) - && droneman->z >= droneman->ceilingz - droneman->height) + && droneman->z + droneman->height >= mobj->z + mobj->height) droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); for (i = 0; i < MAXPLAYERS; i++) @@ -7890,8 +7888,8 @@ void P_MobjThinker(mobj_t *mobj) if (bonustime) { CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); - if (droneman && droneman->state != &states[S_INVISIBLE]) - P_SetMobjState(droneman, S_INVISIBLE); + if (droneman && !(droneman->flags2 & MF2_DONTDRAW)) + droneman->flags2 |= MF2_DONTDRAW; if (goalpost && goalpost->state == &states[S_INVISIBLE]) P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); if (sparkle && sparkle->state == &states[S_INVISIBLE]) @@ -7913,14 +7911,19 @@ void P_MobjThinker(mobj_t *mobj) P_SetMobjState(goalpost, S_INVISIBLE); if (sparkle && sparkle->state != &states[S_INVISIBLE]) P_SetMobjState(sparkle, S_INVISIBLE); - if (droneman && droneman->state == &states[S_INVISIBLE]) - P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + if (droneman) + { + if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) + P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + if (droneman->flags2 & MF2_DONTDRAW) + droneman->flags2 &= ~MF2_DONTDRAW; + } } else { // else, hide it - if (droneman && droneman->state != &states[S_INVISIBLE]) - P_SetMobjState(droneman, S_INVISIBLE); + if (droneman && !(droneman->flags2 & MF2_DONTDRAW)) + droneman->flags2 |= MF2_DONTDRAW; } } } From 76dc4d99bcc1ea2606d8967493f411c8da9ed470 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 12:06:17 -0400 Subject: [PATCH 10/26] Remove ORBIDYA CENTER states, we don't need 'em --- src/dehacked.c | 13 ------------- src/info.c | 17 ++--------------- src/info.h | 13 ------------- 3 files changed, 2 insertions(+), 41 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index fd289dc18..5c2953a55 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6041,24 +6041,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ORBITEM6", "S_ORBITEM7", "S_ORBITEM8", - "S_ORBITEM1_CENTER", - "S_ORBITEM2_CENTER", - "S_ORBITEM3_CENTER", - "S_ORBITEM4_CENTER", - "S_ORBITEM5_CENTER", - "S_ORBITEM6_CENTER", - "S_ORBITEM7_CENTER", - "S_ORBITEM8_CENTER", "S_ORBIDYA1", "S_ORBIDYA2", "S_ORBIDYA3", "S_ORBIDYA4", "S_ORBIDYA5", - "S_ORBIDYA1_CENTER", - "S_ORBIDYA2_CENTER", - "S_ORBIDYA3_CENTER", - "S_ORBIDYA4_CENTER", - "S_ORBIDYA5_CENTER", // "Flicky" helper "S_NIGHTOPIANHELPER1", diff --git a/src/info.c b/src/info.c index 38ba0bdf6..e6b4e8314 100644 --- a/src/info.c +++ b/src/info.c @@ -3338,24 +3338,11 @@ state_t states[NUMSTATES] = {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM6}, // S_ORBITEM6 {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM7}, // S_ORBITEM7 {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBITEM8}, // S_ORBITEM8 - {SPR_CEMG, FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM1_CENTER}, // S_ORBITEM1_CENTER - {SPR_CEMG, FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM2_CENTER}, // S_ORBITEM2_CENTER - {SPR_CEMG, FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM3_CENTER}, // S_ORBITEM3_CENTER - {SPR_CEMG, FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM4_CENTER}, // S_ORBITEM4_CENTER - {SPR_CEMG, FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM5_CENTER}, // S_ORBITEM5_CENTER - {SPR_CEMG, FF_FULLBRIGHT|5, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM6_CENTER}, // S_ORBITEM6_CENTER - {SPR_CEMG, FF_FULLBRIGHT|6, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM7_CENTER}, // S_ORBITEM7_CENTER - {SPR_CEMG, FF_FULLBRIGHT|7, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBITEM8_CENTER}, // S_ORBITEM8_CENTER {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA1}, // S_ORBIDYA1 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA2}, // S_ORBIDYA2 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA3}, // S_ORBIDYA3 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA4}, // S_ORBIDYA4 {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0, S_ORBIDYA5}, // S_ORBIDYA5 - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA1_CENTER}, // S_ORBIDYA1_CENTER - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|1, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA2_CENTER}, // S_ORBIDYA2_CENTER - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|2, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA3_CENTER}, // S_ORBIDYA3_CENTER - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|3, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA4_CENTER}, // S_ORBIDYA4_CENTER - {SPR_IDYA, FF_TRANS20|FF_FULLBRIGHT|4, 1, {A_OrbitNights}, ANG2*2, 0x3000000, S_ORBIDYA5_CENTER}, // S_ORBIDYA5_CENTER // Flicky helper for NiGHTS {SPR_FL01, 1, 1, {A_OrbitNights}, ANG2*2, 180 | 0x10000, S_NIGHTOPIANHELPER2}, // S_NIGHTOPIANHELPER1 @@ -14631,7 +14618,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_ORBITEM1, // meleestate S_ORBIDYA1, // missilestate S_XPLD1, // deathstate - S_ORBITEM1_CENTER, // xdeathstate + S_NULL, // xdeathstate sfx_s3k8a, // deathsound 8, // speed 8*FRACUNIT, // radius @@ -14641,7 +14628,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags - S_ORBIDYA1_CENTER // raisestate + S_NULL // raisestate }, { // MT_LOCKON diff --git a/src/info.h b/src/info.h index 11150a114..a386b199a 100644 --- a/src/info.h +++ b/src/info.h @@ -3394,24 +3394,11 @@ typedef enum state S_ORBITEM6, S_ORBITEM7, S_ORBITEM8, - S_ORBITEM1_CENTER, - S_ORBITEM2_CENTER, - S_ORBITEM3_CENTER, - S_ORBITEM4_CENTER, - S_ORBITEM5_CENTER, - S_ORBITEM6_CENTER, - S_ORBITEM7_CENTER, - S_ORBITEM8_CENTER, S_ORBIDYA1, S_ORBIDYA2, S_ORBIDYA3, S_ORBIDYA4, S_ORBIDYA5, - S_ORBIDYA1_CENTER, - S_ORBIDYA2_CENTER, - S_ORBIDYA3_CENTER, - S_ORBIDYA4_CENTER, - S_ORBIDYA5_CENTER, // "Flicky" helper S_NIGHTOPIANHELPER1, From d8cafeba7da891d80da5dd6eedf1b66b52d4386c Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 12:06:50 -0400 Subject: [PATCH 11/26] Remove A_OrbitNights additional input offset on current target Z, don't need it --- src/p_enemy.c | 11 +++-------- src/p_inter.c | 23 +++-------------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 40adb9d4a..68d01c163 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8544,14 +8544,12 @@ void A_ToggleFlameJet(mobj_t* actor) // var1 = Angle adjustment (aka orbit speed) // var2: // Lower 16 bits: height offset -// Upper 8 bits: set if object is Nightopian Helper -// Highest 8 bits: center height offset to target by this divisor +// Upper 16 bits: set if object is Nightopian Helper // void A_OrbitNights(mobj_t* actor) { INT32 ofs = (var2 & 0xFFFF); - boolean ishelper = ((var2 >> 16) & 0xFF); - INT32 ofsdiv = var2 >> 24; + boolean ishelper = var2 >> 16; #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; @@ -8581,10 +8579,7 @@ void A_OrbitNights(mobj_t* actor) actor->x = actor->target->x + fc; actor->y = actor->target->y + fs; - if (ofsdiv) - actor->z = (actor->target->z + actor->target->height / ofsdiv) + fh + FixedMul(16*FRACUNIT, actor->scale); - else - actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); + actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale); // Semi-lazy hack actor->angle = (angle_t)actor->extravalue1 + ANGLE_90; diff --git a/src/p_inter.c b/src/p_inter.c index 99b43dbfd..86c253e4c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -799,19 +799,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { if (toucher->tracer) // Move the ideya over to the drone! { - statenum_t currentstate = toucher->tracer->state - states; mobj_t *hnext = special->hnext; P_SetTarget(&special->hnext, toucher->tracer); P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - P_SetTarget(&special->hnext->target, special); - - // switch to centered orbit states - if (currentstate >= mobjinfo[MT_GOTEMERALD].missilestate - && currentstate <= mobjinfo[MT_GOTEMERALD].missilestate + 4) - P_SetMobjState(toucher->tracer, - mobjinfo[MT_GOTEMERALD].raisestate + currentstate - mobjinfo[MT_GOTEMERALD].missilestate); - + P_SetTarget(&special->hnext->target, special->target ? special->target : special); // goalpost P_SetTarget(&toucher->tracer, NULL); + if (hnext) { special->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); @@ -821,19 +814,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } if (player->exiting) // ...then move it back? { - mobj_t *hnext = special; - statenum_t currentstate; + mobj_t *hnext = special->target ? special->target : special; // goalpost while ((hnext = hnext->hnext)) - { P_SetTarget(&hnext->target, toucher); - currentstate = hnext->state - states; - - // switch to regular orbit states - if (currentstate >= mobjinfo[MT_GOTEMERALD].raisestate - && currentstate <= mobjinfo[MT_GOTEMERALD].raisestate + 4) - P_SetMobjState(hnext, - mobjinfo[MT_GOTEMERALD].missilestate + currentstate - mobjinfo[MT_GOTEMERALD].raisestate); - } } return; } From 14301a62d591a768e1dd29552d4e194121f6b73c Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 15:49:34 -0400 Subject: [PATCH 12/26] Make Drone hitbox height and player Z alignment configurable * Default hitbox height is 80 * Drone Thing parameter sets height to multiples of 32 * Player aligns by default to bottom+24 of hitbox (offsetted) * `MTF_OBJECTSPECIAL` aligns player to hitbox top * `MTF_EXTRA` aligns to hitbox center * `MTF_OBJECTSPECIAL|MTF_EXTRA` aligns to real bottom of hitbox * Goalpost and sparkle Z alignment is changed to reflect configurableness --- src/info.c | 6 +-- src/p_mobj.c | 147 +++++++++++++++++++++++++++++++++++++++++++++------ src/p_user.c | 33 +++++++++++- 3 files changed, 166 insertions(+), 20 deletions(-) diff --git a/src/info.c b/src/info.c index e6b4e8314..f1d78c85e 100644 --- a/src/info.c +++ b/src/info.c @@ -16116,7 +16116,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height + 80*FRACUNIT, // height 1, // display offset 1000, // mass 0, // damage @@ -16170,7 +16170,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height + 24*FRACUNIT, // height 1, // display offset 1000, // mass 0, // damage @@ -16197,7 +16197,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius - 56*FRACUNIT, // height + 24*FRACUNIT, // height -1, // display offset 1000, // mass 0, // damage diff --git a/src/p_mobj.c b/src/p_mobj.c index 8d6382f2f..1302ca977 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7866,16 +7866,44 @@ void P_MobjThinker(mobj_t *mobj) // Invisible/bouncing mode. else { + boolean flip = mobj->flags2 & MF2_OBJECTFLIP; + boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); + boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + fixed_t droneboxmandiff = max(mobj->height - droneman->height, 0); + INT32 i; boolean bonustime = false; + fixed_t zcomp; + + if (!flip) + { + if (topaligned) + zcomp = droneboxmandiff + mobj->z; + else if (middlealigned) + zcomp = (droneboxmandiff / 2) + mobj->z; + else if (bottomoffsetted) + zcomp = mobj->z + FixedMul(24*FRACUNIT, mobj->scale); + else + zcomp = mobj->z; + } + else + { + if (topaligned) + zcomp = mobj->z; + else if (middlealigned) + zcomp = (droneboxmandiff / 2) + mobj->z; + else if (bottomoffsetted) + zcomp = mobj->z + droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + else + zcomp = mobj->z + droneboxmandiff; + } // Bouncy bouncy! droneman->angle += ANG10; - if (!(droneman->flags2 & MF2_OBJECTFLIP) - && droneman->z <= mobj->z) + if (!flip && droneman->z <= zcomp) droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); - else if ((droneman->flags2 & MF2_OBJECTFLIP) - && droneman->z + droneman->height >= mobj->z + mobj->height) + else if (flip && droneman->z >= zcomp) droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); for (i = 0; i < MAXPLAYERS; i++) @@ -10541,24 +10569,111 @@ ML_EFFECT4 : Don't clip inside the ground mobj->threshold = mthing->angle >> 8; break; case MT_NIGHTSDRONE: - if (mthing->angle > 0) - mobj->health = mthing->angle; - - if (mthing->options & MTF_OBJECTFLIP) { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } + boolean flip = mthing->options & MTF_OBJECTFLIP; + boolean topaligned = (mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); + boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); + boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); - // spawn visual components - { - mobj_t *goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_GOAL); - mobj_t *sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_SPARKLING); - mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_NIGHTSDRONE_MAN); + fixed_t droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); + fixed_t dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); + + INT16 timelimit = mthing->angle; + fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; + fixed_t oldheight = mobj->height; + // if you want to use parameter for something else, do this instead: + // timelimit = mthing->angle & 0xFFF; hitboxheight = (mthing->extrainfo >> 12) * 32 * FRACUNIT; + fixed_t dronemanoffset, goaloffset, sparkleoffset; + + if (mthing->angle > 0) + mobj->health = timelimit; + + if (hitboxheight > 0) + mobj->height = hitboxheight; + else + mobj->height = mobjinfo[MT_NIGHTSDRONE].height; + + if (flip && mobj->height != oldheight) + P_TeleportMove(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); + + if (!flip) + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = 24*FRACUNIT; + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); + } + else + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); + } + + // spawn visual elements + mobj_t *goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, goaloffset, MT_NIGHTSDRONE_GOAL); + mobj_t *sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, sparkleoffset, MT_NIGHTSDRONE_SPARKLING); + mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, dronemanoffset, MT_NIGHTSDRONE_MAN); P_SetTarget(&mobj->target, goalpost); P_SetTarget(&goalpost->target, sparkle); P_SetTarget(&goalpost->tracer, droneman); + + // correct Z position + if (flip) + { + P_TeleportMove(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset); + P_TeleportMove(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset); + P_TeleportMove(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset); + } + + // Remember position preference for later + if (topaligned) + mobj->flags |= MF_SLIDEME; + else if (middlealigned) + mobj->flags |= MF_GRENADEBOUNCE; + else if (!bottomoffsetted) + mobj->flags |= MF_SLIDEME | MF_GRENADEBOUNCE; } break; case MT_HIVEELEMENTAL: diff --git a/src/p_user.c b/src/p_user.c index 22ac51df1..8c50b5095 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6114,8 +6114,39 @@ static void P_MoveNiGHTSToDrone(player_t *player) { if (!player->drone) return; + + boolean flip = player->drone->flags2 & MF2_OBJECTFLIP; + boolean topaligned = (player->drone->flags & MF_SLIDEME) && !(player->drone->flags & MF_GRENADEBOUNCE); + boolean middlealigned = (player->drone->flags & MF_GRENADEBOUNCE) && !(player->drone->flags & MF_SLIDEME); + boolean bottomoffsetted = !(player->drone->flags & MF_SLIDEME) && !(player->drone->flags & MF_GRENADEBOUNCE); + fixed_t droneboxmandiff = max(player->drone->height - player->mo->height, 0); + fixed_t zofs; + + if (!flip) + { + if (topaligned) + zofs = droneboxmandiff; + else if (middlealigned) + zofs = droneboxmandiff / 2; + else if (bottomoffsetted) + zofs = FixedMul(24*FRACUNIT, player->drone->scale); + else + zofs = 0; + } + else + { + if (topaligned) + zofs = 0; + else if (middlealigned) + zofs = droneboxmandiff / 2; + else if (bottomoffsetted) + zofs = droneboxmandiff - FixedMul(24*FRACUNIT, player->drone->scale); + else + zofs = droneboxmandiff; + } + player->mo->momx = player->mo->momy = player->mo->momz = 0; - P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z + player->drone->height/2 - player->mo->height/2); + P_TeleportMove(player->mo, player->drone->x, player->drone->y, player->drone->z + zofs); P_SetTarget(&player->drone, NULL); } From 291a955d2432c9223d24d3d3f2a0f6923cc6d1d2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 15:54:39 -0400 Subject: [PATCH 13/26] Don't need this line --- src/p_mobj.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1302ca977..de2ed16ac 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8801,8 +8801,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->fuse += 30 * TICRATE; break; case MT_NIGHTSDRONE: - if (G_IsSpecialStage(gamemap)) - mobj->flags2 |= MF2_DONTDRAW; nummaprings = -1; // no perfect bonus, rings are free break; case MT_EGGCAPSULE: From 006f33d72fa5f2ced68cbfc489eaefc89994c76a Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 20:49:16 -0400 Subject: [PATCH 14/26] Line fixes for visual element positioning # Conflicts: # src/p_mobj.c --- src/p_mobj.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index de2ed16ac..66608332c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10573,15 +10573,13 @@ ML_EFFECT4 : Don't clip inside the ground boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); - fixed_t droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); - fixed_t dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); - INT16 timelimit = mthing->angle; fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; fixed_t oldheight = mobj->height; // if you want to use parameter for something else, do this instead: // timelimit = mthing->angle & 0xFFF; hitboxheight = (mthing->extrainfo >> 12) * 32 * FRACUNIT; - fixed_t dronemanoffset, goaloffset, sparkleoffset; + fixed_t oldheight = mobj->height; + fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; if (mthing->angle > 0) mobj->health = timelimit; @@ -10591,6 +10589,9 @@ ML_EFFECT4 : Don't clip inside the ground else mobj->height = mobjinfo[MT_NIGHTSDRONE].height; + droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); + dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); + if (flip && mobj->height != oldheight) P_TeleportMove(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); From 8c63bf9fe8f493d0f516a40219c0972a24f146a2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 19:40:26 -0400 Subject: [PATCH 15/26] NIGHTSDRONE visual element position syncing: XYZ and OBJECTFLIP --- src/p_mobj.c | 146 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 126 insertions(+), 20 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 66608332c..31d643fe5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7828,10 +7828,19 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_NIGHTSDRONE: { + // variable setup mobj_t *goalpost = NULL; mobj_t *sparkle = NULL; mobj_t *droneman = NULL; + boolean flip = mobj->flags2 & MF2_OBJECTFLIP; + boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); + boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean flipchanged = false; + + fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; + if (mobj->target && mobj->target->type == MT_NIGHTSDRONE_GOAL) { goalpost = mobj->target; @@ -7841,6 +7850,108 @@ void P_MobjThinker(mobj_t *mobj) droneman = goalpost->tracer; } + if (!goalpost || !sparkle || !droneman) + break; + + // did NIGHTSDRONE position, scale, or flip change? all elements need to be synced + droneboxmandiff = max(mobj->height - droneman->height, 0); + dronemangoaldiff = max(droneman->height - goalpost->height, 0); + + if (!(goalpost->flags2 & MF2_OBJECTFLIP) && (mobj->flags2 & MF2_OBJECTFLIP)) + { + goalpost->eflags |= MFE_VERTICALFLIP; + goalpost->flags2 |= MF2_OBJECTFLIP; + sparkle->eflags |= MFE_VERTICALFLIP; + sparkle->flags2 |= MF2_OBJECTFLIP; + droneman->eflags |= MFE_VERTICALFLIP; + droneman->flags2 |= MF2_OBJECTFLIP; + flipchanged = true; + } + else if ((goalpost->flags2 & MF2_OBJECTFLIP) && !(mobj->flags2 & MF2_OBJECTFLIP)) + { + goalpost->eflags &= ~MFE_VERTICALFLIP; + goalpost->flags2 &= ~MF2_OBJECTFLIP; + sparkle->eflags &= ~MFE_VERTICALFLIP; + sparkle->flags2 &= ~MF2_OBJECTFLIP; + droneman->eflags &= ~MFE_VERTICALFLIP; + droneman->flags2 &= ~MF2_OBJECTFLIP; + flipchanged = true; + } + + if (goalpost->destscale != mobj->destscale || goalpost->movefactor != mobj->z || flipchanged) + { + goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; + goalpost->movefactor = mobj->z; + + // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE + if (!flip) + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = 24*FRACUNIT; + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); + } + else + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff / 2; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff / 2 + dronemanoffset; + } + + sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); + } + + P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + FixedMul(goaloffset, mobj->scale)); + P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + FixedMul(sparkleoffset, mobj->scale)); + } + else if (goalpost->x != mobj->x || goalpost->y != mobj->y) + { + P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); + P_TeleportMove(sparkle, mobj->x, mobj->y, goalpost->z); + } + + if (droneman->x != mobj->x || droneman->y != mobj->y) + { + // we just care about x/y positioning; z takes care of itself + P_TeleportMove(droneman, mobj->x, mobj->y, + droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); + } + + // now toggle states! // GOAL mode? if (sparkle->state >= &states[S_NIGHTSDRONE_SPARKLING1] && sparkle->state <= &states[S_NIGHTSDRONE_SPARKLING16]) { @@ -7866,16 +7977,12 @@ void P_MobjThinker(mobj_t *mobj) // Invisible/bouncing mode. else { - boolean flip = mobj->flags2 & MF2_OBJECTFLIP; - boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); - boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); - boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); fixed_t droneboxmandiff = max(mobj->height - droneman->height, 0); - INT32 i; boolean bonustime = false; fixed_t zcomp; + // Bouncy bouncy! if (!flip) { if (topaligned) @@ -7899,13 +8006,13 @@ void P_MobjThinker(mobj_t *mobj) zcomp = mobj->z + droneboxmandiff; } - // Bouncy bouncy! droneman->angle += ANG10; if (!flip && droneman->z <= zcomp) droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); else if (flip && droneman->z >= zcomp) droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); + // state switching logic for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) { @@ -7916,11 +8023,11 @@ void P_MobjThinker(mobj_t *mobj) if (bonustime) { CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); - if (droneman && !(droneman->flags2 & MF2_DONTDRAW)) + if (!(droneman->flags2 & MF2_DONTDRAW)) droneman->flags2 |= MF2_DONTDRAW; - if (goalpost && goalpost->state == &states[S_INVISIBLE]) + if (goalpost->state == &states[S_INVISIBLE]) P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); - if (sparkle && sparkle->state == &states[S_INVISIBLE]) + if (sparkle->state == &states[S_INVISIBLE]) P_SetMobjState(sparkle, mobjinfo[sparkle->type].meleestate); } else if (!G_IsSpecialStage(gamemap)) @@ -7935,22 +8042,19 @@ void P_MobjThinker(mobj_t *mobj) if (bonustime) { // show droneman if at least one player is non-nights - if (goalpost && goalpost->state != &states[S_INVISIBLE]) + if (goalpost->state != &states[S_INVISIBLE]) P_SetMobjState(goalpost, S_INVISIBLE); - if (sparkle && sparkle->state != &states[S_INVISIBLE]) + if (sparkle->state != &states[S_INVISIBLE]) P_SetMobjState(sparkle, S_INVISIBLE); - if (droneman) - { - if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) - P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); - if (droneman->flags2 & MF2_DONTDRAW) - droneman->flags2 &= ~MF2_DONTDRAW; - } + if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) + P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + if (droneman->flags2 & MF2_DONTDRAW) + droneman->flags2 &= ~MF2_DONTDRAW; } else { // else, hide it - if (droneman && !(droneman->flags2 & MF2_DONTDRAW)) + if (!(droneman->flags2 & MF2_DONTDRAW)) droneman->flags2 |= MF2_DONTDRAW; } } @@ -10575,7 +10679,6 @@ ML_EFFECT4 : Don't clip inside the ground INT16 timelimit = mthing->angle; fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; - fixed_t oldheight = mobj->height; // if you want to use parameter for something else, do this instead: // timelimit = mthing->angle & 0xFFF; hitboxheight = (mthing->extrainfo >> 12) * 32 * FRACUNIT; fixed_t oldheight = mobj->height; @@ -10658,6 +10761,9 @@ ML_EFFECT4 : Don't clip inside the ground P_SetTarget(&goalpost->target, sparkle); P_SetTarget(&goalpost->tracer, droneman); + // Remember old Z position for correction detection + goalpost->movefactor = mobj->z; + // correct Z position if (flip) { From f6c39495a8642cb614c641a4d7644df57be55884 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 22:13:33 -0400 Subject: [PATCH 16/26] Fix orbiting Ideya bug, now player gets them back again on exit --- src/p_inter.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 86c253e4c..454f09591 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -799,17 +799,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { if (toucher->tracer) // Move the ideya over to the drone! { - mobj_t *hnext = special->hnext; - P_SetTarget(&special->hnext, toucher->tracer); - P_SetTarget(&special->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - P_SetTarget(&special->hnext->target, special->target ? special->target : special); // goalpost + mobj_t *orbittarget = special->target ? special->target : special; + mobj_t *hnext = orbittarget->hnext; + P_SetTarget(&orbittarget->hnext, toucher->tracer); + P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. + P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost P_SetTarget(&toucher->tracer, NULL); if (hnext) { - special->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); - if (special->hnext->extravalue1 > hnext->extravalue1) - special->hnext->extravalue1 -= (72*ANG1)/special->hnext->extravalue1; + orbittarget->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); + if (orbittarget->hnext->extravalue1 > hnext->extravalue1) + orbittarget->hnext->extravalue1 -= (72*ANG1)/orbittarget->hnext->extravalue1; } } if (player->exiting) // ...then move it back? From 60025e396b40a2547dbed09b2af88085534a070e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 22:41:58 -0400 Subject: [PATCH 17/26] NIGHTSDRONE visual element positioning now works with scaling --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 31d643fe5..1e28ae1a4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7935,8 +7935,8 @@ void P_MobjThinker(mobj_t *mobj) sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); } - P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + FixedMul(goaloffset, mobj->scale)); - P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + FixedMul(sparkleoffset, mobj->scale)); + P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); + P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); } else if (goalpost->x != mobj->x || goalpost->y != mobj->y) { From 154cfa1171f296f3218fe87f9ae9417932bdabcc Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 23:15:28 -0400 Subject: [PATCH 18/26] When NIGHTSDRONE z changes, change DRONEMAN z as well --- src/p_mobj.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1e28ae1a4..20af2e763 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7881,7 +7881,6 @@ void P_MobjThinker(mobj_t *mobj) if (goalpost->destscale != mobj->destscale || goalpost->movefactor != mobj->z || flipchanged) { goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; - goalpost->movefactor = mobj->z; // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE if (!flip) @@ -7937,6 +7936,11 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); + if (goalpost->movefactor != mobj->z) + { + P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); + goalpost->movefactor = mobj->z; + } } else if (goalpost->x != mobj->x || goalpost->y != mobj->y) { @@ -7945,11 +7949,10 @@ void P_MobjThinker(mobj_t *mobj) } if (droneman->x != mobj->x || droneman->y != mobj->y) - { - // we just care about x/y positioning; z takes care of itself + // More complex changes like Z, gravity, and flags are handled earlier. + // Here, we just care if only X/Y changes. P_TeleportMove(droneman, mobj->x, mobj->y, droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); - } // now toggle states! // GOAL mode? From e50f7fa412f5d65ec69081d2119a694c604f376b Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 23:32:12 -0400 Subject: [PATCH 19/26] NIGHTSDRONE sync visual elements when changing mobj flags --- src/p_mobj.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 20af2e763..3aa68e521 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7853,7 +7853,7 @@ void P_MobjThinker(mobj_t *mobj) if (!goalpost || !sparkle || !droneman) break; - // did NIGHTSDRONE position, scale, or flip change? all elements need to be synced + // did NIGHTSDRONE position, scale, flip, or flags change? all elements need to be synced droneboxmandiff = max(mobj->height - droneman->height, 0); dronemangoaldiff = max(droneman->height - goalpost->height, 0); @@ -7878,7 +7878,10 @@ void P_MobjThinker(mobj_t *mobj) flipchanged = true; } - if (goalpost->destscale != mobj->destscale || goalpost->movefactor != mobj->z || flipchanged) + if (goalpost->destscale != mobj->destscale + || goalpost->movefactor != mobj->z + || flipchanged + || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; @@ -7941,18 +7944,20 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); goalpost->movefactor = mobj->z; } + goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); } - else if (goalpost->x != mobj->x || goalpost->y != mobj->y) + else { - P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); - P_TeleportMove(sparkle, mobj->x, mobj->y, goalpost->z); - } + if (goalpost->x != mobj->x || goalpost->y != mobj->y) + { + P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); + P_TeleportMove(sparkle, mobj->x, mobj->y, goalpost->z); + } - if (droneman->x != mobj->x || droneman->y != mobj->y) - // More complex changes like Z, gravity, and flags are handled earlier. - // Here, we just care if only X/Y changes. - P_TeleportMove(droneman, mobj->x, mobj->y, - droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); + if (droneman->x != mobj->x || droneman->y != mobj->y) + P_TeleportMove(droneman, mobj->x, mobj->y, + droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); + } // now toggle states! // GOAL mode? @@ -10764,9 +10769,6 @@ ML_EFFECT4 : Don't clip inside the ground P_SetTarget(&goalpost->target, sparkle); P_SetTarget(&goalpost->tracer, droneman); - // Remember old Z position for correction detection - goalpost->movefactor = mobj->z; - // correct Z position if (flip) { @@ -10782,6 +10784,10 @@ ML_EFFECT4 : Don't clip inside the ground mobj->flags |= MF_GRENADEBOUNCE; else if (!bottomoffsetted) mobj->flags |= MF_SLIDEME | MF_GRENADEBOUNCE; + + // Remember old Z position and flags for correction detection + goalpost->movefactor = mobj->z; + goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); } break; case MT_HIVEELEMENTAL: From b534e01e2857965e27368f5b988b71413ef52760 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 11 Aug 2018 23:53:07 -0400 Subject: [PATCH 20/26] Scale Ideyas when moving to/from NIGHTSDRONE and scaling changes to NIGHTSDRONE --- src/p_inter.c | 3 +++ src/p_mobj.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 454f09591..e05f18364 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -801,11 +801,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *orbittarget = special->target ? special->target : special; mobj_t *hnext = orbittarget->hnext; + P_SetTarget(&orbittarget->hnext, toucher->tracer); P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost P_SetTarget(&toucher->tracer, NULL); + orbittarget->hnext->destscale = orbittarget->destscale; + if (hnext) { orbittarget->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); diff --git a/src/p_mobj.c b/src/p_mobj.c index 3aa68e521..2450743b7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7883,7 +7883,14 @@ void P_MobjThinker(mobj_t *mobj) || flipchanged || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { - goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; + if (goalpost->destscale != mobj->destscale) + { + goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; + // get the orbiting ideyas and scale them too + mobj_t *hnext = goalpost; + while ((hnext = hnext->hnext)) + hnext->destscale = mobj->destscale; + } // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE if (!flip) From 89cf2b879360ecadd58e98be70daec783c1e9598 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 12 Aug 2018 01:07:26 -0400 Subject: [PATCH 21/26] A_OrbitNights make actor scale to target * Added `donotrescale` input to disable this behavior * Reverted previous commit changes for scaling Ideya because unneeded --- src/p_enemy.c | 9 +++++++-- src/p_inter.c | 2 -- src/p_mobj.c | 9 +-------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 68d01c163..06223eb7a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8544,12 +8544,14 @@ void A_ToggleFlameJet(mobj_t* actor) // var1 = Angle adjustment (aka orbit speed) // var2: // Lower 16 bits: height offset -// Upper 16 bits: set if object is Nightopian Helper +// Bits 17-20: set if object is Nightopian Helper +// Bits 21-24: set to not sync scale to player // void A_OrbitNights(mobj_t* actor) { INT32 ofs = (var2 & 0xFFFF); - boolean ishelper = var2 >> 16; + boolean ishelper = (var2 & 0xF0000); + boolean donotrescale = (var2 & 0xF00000); #ifdef HAVE_BLUA if (LUA_CallAction("A_OrbitNights", actor)) return; @@ -8594,6 +8596,9 @@ void A_OrbitNights(mobj_t* actor) else actor->flags2 &= ~MF2_DONTDRAW; } + + if (!donotrescale && actor->destscale != actor->target->destscale) + actor->destscale = actor->target->destscale; } } diff --git a/src/p_inter.c b/src/p_inter.c index e05f18364..66c6bd852 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -807,8 +807,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost P_SetTarget(&toucher->tracer, NULL); - orbittarget->hnext->destscale = orbittarget->destscale; - if (hnext) { orbittarget->hnext->extravalue1 = (angle_t)(hnext->extravalue1 - 72*ANG1); diff --git a/src/p_mobj.c b/src/p_mobj.c index 2450743b7..3aa68e521 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7883,14 +7883,7 @@ void P_MobjThinker(mobj_t *mobj) || flipchanged || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { - if (goalpost->destscale != mobj->destscale) - { - goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; - // get the orbiting ideyas and scale them too - mobj_t *hnext = goalpost; - while ((hnext = hnext->hnext)) - hnext->destscale = mobj->destscale; - } + goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE if (!flip) From 01436d2a65cd688af2ea59b9b75318edf5504308 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 12 Aug 2018 09:28:04 -0400 Subject: [PATCH 22/26] For safety, clear MF_SLIDEME and MF_GRENADEBOUNCE flags before using --- src/p_mobj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 3aa68e521..fe78fa79d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10778,6 +10778,7 @@ ML_EFFECT4 : Don't clip inside the ground } // Remember position preference for later + mobj->flags &= ~(MF_SLIDEME | MF_GRENADEBOUNCE); if (topaligned) mobj->flags |= MF_SLIDEME; else if (middlealigned) From b17f3e7e403a57fd03e9b6640e6638eddb2326ac Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 12 Aug 2018 12:42:21 -0400 Subject: [PATCH 23/26] Set Drone hitbox radius by upmost 4 bits of Angle --- src/info.c | 2 +- src/p_mobj.c | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/info.c b/src/info.c index f1d78c85e..fc30011bf 100644 --- a/src/info.c +++ b/src/info.c @@ -16121,7 +16121,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // mass 0, // damage sfx_ideya, // activesound - MF_NOGRAVITY|MF_SPECIAL, // flags + MF_NOGRAVITY|MF_NOCLIP|MF_SPECIAL, // flags S_NULL // raisestate }, diff --git a/src/p_mobj.c b/src/p_mobj.c index fe78fa79d..5292ef15e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10685,16 +10685,18 @@ ML_EFFECT4 : Don't clip inside the ground boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); - INT16 timelimit = mthing->angle; + INT16 timelimit = mthing->angle & 0xFFF; + fixed_t hitboxradius = (mthing->angle & 0xF000) * 32 * FRACUNIT; fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; - // if you want to use parameter for something else, do this instead: - // timelimit = mthing->angle & 0xFFF; hitboxheight = (mthing->extrainfo >> 12) * 32 * FRACUNIT; fixed_t oldheight = mobj->height; fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; - if (mthing->angle > 0) + if (timelimit > 0) mobj->health = timelimit; + if (hitboxradius > 0) + mobj->radius = hitboxradius; + if (hitboxheight > 0) mobj->height = hitboxheight; else From 3170d317088b89c0b4f826616af383fc52dd29c7 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 04:49:32 -0400 Subject: [PATCH 24/26] Correct hitboxradius value; proper sparkle->z when moving x/y --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5292ef15e..2a3e8cc84 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7951,7 +7951,7 @@ void P_MobjThinker(mobj_t *mobj) if (goalpost->x != mobj->x || goalpost->y != mobj->y) { P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); - P_TeleportMove(sparkle, mobj->x, mobj->y, goalpost->z); + P_TeleportMove(sparkle, mobj->x, mobj->y, sparkle->z); } if (droneman->x != mobj->x || droneman->y != mobj->y) @@ -10686,7 +10686,7 @@ ML_EFFECT4 : Don't clip inside the ground boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); INT16 timelimit = mthing->angle & 0xFFF; - fixed_t hitboxradius = (mthing->angle & 0xF000) * 32 * FRACUNIT; + fixed_t hitboxradius = ((mthing->angle & 0xF000) >> 12) * 32 * FRACUNIT; fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; fixed_t oldheight = mobj->height; fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; From 539c323838c4f7e348e98e3fde26aa42bbe7093f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 13 Aug 2018 09:50:50 -0400 Subject: [PATCH 25/26] Make Drone visual elements react to height change --- src/p_mobj.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2a3e8cc84..c7efd9081 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7880,6 +7880,7 @@ void P_MobjThinker(mobj_t *mobj) if (goalpost->destscale != mobj->destscale || goalpost->movefactor != mobj->z + || goalpost->friction != mobj->height || flipchanged || goalpost->threshold != (mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) { @@ -7939,10 +7940,11 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); - if (goalpost->movefactor != mobj->z) + if (goalpost->movefactor != mobj->z || goalpost->friction != mobj->height) { P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; } goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); } @@ -10790,6 +10792,7 @@ ML_EFFECT4 : Don't clip inside the ground // Remember old Z position and flags for correction detection goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); } break; From 0a110d9ef41fa485983a6ca1568ce3842ae4fb02 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 14 Aug 2018 17:21:49 -0400 Subject: [PATCH 26/26] Ideya fixes when a player has more than one Ideya # Conflicts: # src/p_inter.c --- src/p_inter.c | 11 +++++++---- src/p_mobj.c | 1 + src/p_user.c | 10 ++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 66c6bd852..6378762ea 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -803,8 +803,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) mobj_t *hnext = orbittarget->hnext; P_SetTarget(&orbittarget->hnext, toucher->tracer); - P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. - P_SetTarget(&orbittarget->hnext->target, orbittarget); // goalpost + if (!orbittarget->hnext->hnext) + P_SetTarget(&orbittarget->hnext->hnext, hnext); // Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo. + else + P_SetTarget(&orbittarget->hnext->hnext->target, orbittarget); + P_SetTarget(&orbittarget->hnext->target, orbittarget); P_SetTarget(&toucher->tracer, NULL); if (hnext) @@ -962,8 +965,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_carry] == CR_NIGHTSMODE && !toucher->target) return; - if (toucher->tracer) - return; // Don't have multiple ideya + if (toucher->tracer && toucher->tracer->health > 0) + return; // Don't have multiple ideya, unless it's the first one given (health = 0) if (player->mare != special->threshold) // wrong mare return; diff --git a/src/p_mobj.c b/src/p_mobj.c index c7efd9081..19c140d40 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9612,6 +9612,7 @@ void P_SpawnPlayer(INT32 playernum) if (p == players) // this is totally the wrong place to do this aaargh. { mobj_t *idya = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_GOTEMERALD); + idya->health = 0; // for identification P_SetTarget(&idya->target, mobj); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate); P_SetTarget(&mobj->tracer, idya); diff --git a/src/p_user.c b/src/p_user.c index 8c50b5095..877910f25 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6055,6 +6055,7 @@ static void P_DoNiGHTSCapsule(player_t *player) UINT8 em = P_GetNextEmerald(); // Only give it to ONE person, and THAT player has to get to the goal! mobj_t *emmo = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); + emmo->health = em; // for identification P_SetTarget(&emmo->target, player->mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); P_SetTarget(&player->mo->tracer, emmo); @@ -6081,8 +6082,17 @@ static void P_DoNiGHTSCapsule(player_t *player) }*/ mobj_t *idya = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height, MT_GOTEMERALD); idya->extravalue2 = player->mare/5; + idya->health = player->mare + 1; // for identification P_SetTarget(&idya->target, player->mo); P_SetMobjState(idya, mobjinfo[MT_GOTEMERALD].missilestate + ((player->mare + 1) % 5)); + + if (player->mo->tracer) + { + P_SetTarget(&idya->hnext, player->mo->tracer); + idya->extravalue1 = (angle_t)(player->mo->tracer->extravalue1 - 72*ANG1); + if (idya->extravalue1 > player->mo->tracer->extravalue1) + idya->extravalue1 -= (72*ANG1)/idya->extravalue1; + } P_SetTarget(&player->mo->tracer, idya); } for (i = 0; i < MAXPLAYERS; i++)