From f6c6621af817d2791b84ae66cbb273933f4d6940 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 23 May 2025 16:21:27 +0200 Subject: [PATCH 1/9] unnest and cleanup P_MobjThinker everything was moved into seperate functions lel --- src/p_mobj.c | 2242 ++++++++++++++++++++++++++------------------------ 1 file changed, 1145 insertions(+), 1097 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 0157963f9..095804cd9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6056,873 +6056,768 @@ angle_t P_MobjPitchAndRoll(mobj_t *mobj) return return_angle; } -// -// P_MobjThinker -// -void P_MobjThinker(mobj_t *mobj) +// Special thinker for scenery objects +// this does not need to return anything +static void P_MobjSceneryThink(mobj_t *mobj) { - I_Assert(mobj != NULL); - I_Assert(!P_MobjWasRemoved(mobj)); - - if (mobj->flags & MF_NOTHINK) + if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker))) return; - // Remove dead target/tracer. - if (mobj->target && P_MobjWasRemoved(mobj->target)) - P_SetTarget(&mobj->target, NULL); - if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) - P_SetTarget(&mobj->tracer, NULL); - // hnext/hprev changes suggested by toaster - if (mobj->hnext && P_MobjWasRemoved(mobj->hnext)) - P_SetTarget(&mobj->hnext, NULL); - if (mobj->hprev && P_MobjWasRemoved(mobj->hprev)) - P_SetTarget(&mobj->hprev, NULL); + if (P_MobjWasRemoved(mobj)) + return; - mobj->flags2 &= ~MF2_PUSHED; - mobj->eflags &= ~(MFE_SPRUNG|MFE_JUSTBOUNCEDWALL); - - tmfloorthing = tmhitthing = NULL; - - // 970 allows ANY mobj to trigger a linedef exec - if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8) + switch (mobj->type) { - sector_t *sec2; + case MT_HOOP: + if (mobj->fuse > 1) + P_MoveHoop(mobj); + else if (mobj->fuse == 1) + mobj->movecount = 1; - sec2 = P_ThingOnSpecial3DFloor(mobj); - if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1) - P_LinedefExecute(sec2->tag, mobj, sec2); - } - - // Slowly scale up/down to reach your destscale. - if (mobj->scale != mobj->destscale) - { - fixed_t oldheight = mobj->height; - UINT8 correctionType = 0; // Don't correct Z position, just gain height - - if (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz - && mobj->type != MT_EGGMOBILE_FIRE) - correctionType = 1; // Correct Z position by centering - else if (mobj->eflags & MFE_VERTICALFLIP) - correctionType = 2; // Correct Z position by moving down - - if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed) - P_SetScale(mobj, mobj->destscale); - else if (mobj->scale < mobj->destscale) - P_SetScale(mobj, mobj->scale + mobj->scalespeed); - else if (mobj->scale > mobj->destscale) - P_SetScale(mobj, mobj->scale - mobj->scalespeed); - - if (correctionType == 1) - mobj->z -= (mobj->height - oldheight)/2; - else if (correctionType == 2) - mobj->z -= mobj->height - oldheight; - - if (mobj->scale == mobj->destscale) - /// \todo Lua hook for "reached destscale"? - switch(mobj->type) + if (mobj->movecount) { - case MT_EGGMOBILE_FIRE: - mobj->destscale = FRACUNIT; - mobj->scalespeed = FRACUNIT>>4; - break; - default: - break; + mobj->fuse++; + + if (mobj->fuse > 32) + { + // Don't kill the hoop center. For the sake of respawning. + //if (mobj->target) + // P_RemoveMobj(mobj->target); + + P_RemoveMobj(mobj); + } } - } - - if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY! - && (signed)(mobj->frame >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2) - // fade out when nearing the end of fuse... - mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT); - - // Special thinker for scenery objects - if (mobj->flags & MF_SCENERY) - { - if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker))) + else + mobj->fuse--; return; + case MT_NIGHTSPARKLE: + if (mobj->tics != -1) + { + mobj->tics--; - if (P_MobjWasRemoved(mobj)) + // you can cycle through multiple states in a tic + if (!mobj->tics) + if (!P_SetMobjState(mobj, mobj->state->nextstate)) + return; // freed itself + } + + P_UnsetThingPosition(mobj); + mobj->x += mobj->momx; + mobj->y += mobj->momy; + mobj->z += mobj->momz; + P_SetThingPosition(mobj); return; + case MT_NIGHTSLOOPHELPER: + if (--mobj->tics <= 0) + P_RemoveMobj(mobj); - switch (mobj->type) - { - case MT_HOOP: - if (mobj->fuse > 1) - P_MoveHoop(mobj); - else if (mobj->fuse == 1) - mobj->movecount = 1; - - if (mobj->movecount) - { - mobj->fuse++; - - if (mobj->fuse > 32) - { - // Don't kill the hoop center. For the sake of respawning. - //if (mobj->target) - // P_RemoveMobj(mobj->target); - - P_RemoveMobj(mobj); - } - } - else - mobj->fuse--; + // Don't touch my fuse! + return; + case MT_OVERLAY: + if (!mobj->target) + { + P_RemoveMobj(mobj); return; - case MT_NIGHTSPARKLE: - if (mobj->tics != -1) - { - mobj->tics--; + } - // you can cycle through multiple states in a tic - if (!mobj->tics) - if (!P_SetMobjState(mobj, mobj->state->nextstate)) - return; // freed itself - } + if (mobj->state == &states[S_PLAY_SIGN]) // hack to make the player sign icon roll with the sign itself + { + mobj->slopepitch = mobj->target->slopepitch; + mobj->sloperoll = mobj->target->sloperoll; + } - P_UnsetThingPosition(mobj); - mobj->x += mobj->momx; - mobj->y += mobj->momy; - mobj->z += mobj->momz; - P_SetThingPosition(mobj); + P_AddOverlay(mobj); + break; + case MT_SHADOW: + if (!mobj->target) + { + P_RemoveMobj(mobj); return; - case MT_NIGHTSLOOPHELPER: - if (--mobj->tics <= 0) - P_RemoveMobj(mobj); + } - // Don't touch my fuse! + K_RollMobjBySlopes(mobj, mobj->target->standingslope); + + P_AddShadow(mobj); + break; + //{ SRB2kart mobs + case MT_ORBINAUT_SHIELD: // Kart orbit/trail items + case MT_JAWZ_SHIELD: + case MT_BANANA_SHIELD: + case MT_SSMINE_SHIELD: + case MT_EGGMANITEM_SHIELD: + case MT_SINK_SHIELD: + if ((mobj->health > 0 + && (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator)) + || (mobj->health <= 0 && P_IsObjectOnGround(mobj)) + || P_CheckDeathPitCollide(mobj)) // When in death state + { + P_RemoveMobj(mobj); return; - case MT_OVERLAY: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return; - } + } - if (mobj->state == &states[S_PLAY_SIGN]) // hack to make the player sign icon roll with the sign itself - { - mobj->slopepitch = mobj->target->slopepitch; - mobj->sloperoll = mobj->target->sloperoll; - } - - P_AddOverlay(mobj); - break; - case MT_SHADOW: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return; - } - - K_RollMobjBySlopes(mobj, mobj->target->standingslope); - - P_AddShadow(mobj); - break; - //{ SRB2kart mobs - case MT_ORBINAUT_SHIELD: // Kart orbit/trail items - case MT_JAWZ_SHIELD: - case MT_BANANA_SHIELD: - case MT_SSMINE_SHIELD: - case MT_EGGMANITEM_SHIELD: - case MT_SINK_SHIELD: - if ((mobj->health > 0 - && (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator)) - || (mobj->health <= 0 && P_IsObjectOnGround(mobj)) - || P_CheckDeathPitCollide(mobj)) // When in death state - { - P_RemoveMobj(mobj); - return; - } - - P_RollPitchMobj(mobj); - break; - case MT_SMOLDERING: + P_RollPitchMobj(mobj); + break; + case MT_SMOLDERING: + if (leveltime % 2 == 0) + { + fixed_t x = P_RandomRange(-35, 35)*mobj->scale; + fixed_t y = P_RandomRange(-35, 35)*mobj->scale; + fixed_t z = P_RandomRange(0, 70)*mobj->scale; + mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE); + P_SetMobjState(smoke, S_OPAQUESMOKE1); + K_MatchGenericExtraFlags(smoke, mobj); + smoke->scale = mobj->scale * 2; + smoke->destscale = mobj->scale * 6; + smoke->momz = P_RandomRange(4, 9)*FRACUNIT*P_MobjFlip(smoke); + } + break; + case MT_BOOMPARTICLE: + { + fixed_t x = P_RandomRange(-16, 16)*mobj->scale; + fixed_t y = P_RandomRange(-16, 16)*mobj->scale; + fixed_t z = P_RandomRange(0, 32)*mobj->scale*P_MobjFlip(mobj); if (leveltime % 2 == 0) { - fixed_t x = P_RandomRange(-35, 35)*mobj->scale; - fixed_t y = P_RandomRange(-35, 35)*mobj->scale; - fixed_t z = P_RandomRange(0, 70)*mobj->scale; + mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_BOSSEXPLODE); + K_MatchGenericExtraFlags(smoke, mobj); + P_SetMobjState(smoke, S_QUICKBOOM1); + smoke->scale = mobj->scale/2; + smoke->destscale = mobj->scale; + smoke->color = mobj->color; + } + else + { mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE); P_SetMobjState(smoke, S_OPAQUESMOKE1); K_MatchGenericExtraFlags(smoke, mobj); - smoke->scale = mobj->scale * 2; - smoke->destscale = mobj->scale * 6; - smoke->momz = P_RandomRange(4, 9)*FRACUNIT*P_MobjFlip(smoke); + smoke->scale = mobj->scale; + smoke->destscale = mobj->scale*2; } - break; - case MT_BOOMPARTICLE: + if (mobj->tics <= TICRATE) { - fixed_t x = P_RandomRange(-16, 16)*mobj->scale; - fixed_t y = P_RandomRange(-16, 16)*mobj->scale; - fixed_t z = P_RandomRange(0, 32)*mobj->scale*P_MobjFlip(mobj); - if (leveltime % 2 == 0) - { - mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_BOSSEXPLODE); - K_MatchGenericExtraFlags(smoke, mobj); - P_SetMobjState(smoke, S_QUICKBOOM1); - smoke->scale = mobj->scale/2; - smoke->destscale = mobj->scale; - smoke->color = mobj->color; - } - else - { - mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE); - P_SetMobjState(smoke, S_OPAQUESMOKE1); - K_MatchGenericExtraFlags(smoke, mobj); - smoke->scale = mobj->scale; - smoke->destscale = mobj->scale*2; - } - if (mobj->tics <= TICRATE) - { - mobj->destscale = FixedDiv(mobj->scale, 100*FRACUNIT); - } + mobj->destscale = FixedDiv(mobj->scale, 100*FRACUNIT); } - break; - case MT_BATTLEBUMPER: - if (mobj->health > 0 && mobj->target && mobj->target->player - && mobj->target->player->health > 0 && !mobj->target->player->spectator) - { - fixed_t rad = 32*mobj->target->scale; - fixed_t offz; - angle_t ang, diff; + } + break; + case MT_BATTLEBUMPER: + if (mobj->health > 0 && mobj->target && mobj->target->player + && mobj->target->player->health > 0 && !mobj->target->player->spectator) + { + fixed_t rad = 32*mobj->target->scale; + fixed_t offz; + angle_t ang, diff; - if (!((mobj->target->player-players) & 1)) - ang = (FixedAngle(mobj->info->speed) * -1); - else - ang = FixedAngle(mobj->info->speed); + if (!((mobj->target->player-players) & 1)) + ang = (FixedAngle(mobj->info->speed) * -1); + else + ang = FixedAngle(mobj->info->speed); - if (mobj->target->player->kartstuff[k_bumper] <= 1) - diff = 0; - else - diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_bumper]); + if (mobj->target->player->kartstuff[k_bumper] <= 1) + diff = 0; + else + diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_bumper]); - ang = (ang*leveltime) + (diff * (mobj->threshold-1)); - - // If the player is on the ceiling, then flip your items as well. - if (mobj->target->eflags & MFE_VERTICALFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - offz = mobj->target->height / 2; - } - else - { - mobj->eflags &= ~MFE_VERTICALFLIP; - offz = mobj->target->height / 5; - } - - if (mobj->target->eflags & MFE_DRAWONLYFORP1) // groooooaann... - mobj->eflags |= MFE_DRAWONLYFORP1; - else - mobj->eflags &= ~MFE_DRAWONLYFORP1; - - if (mobj->target->eflags & MFE_DRAWONLYFORP2) - mobj->eflags |= MFE_DRAWONLYFORP2; - else - mobj->eflags &= ~MFE_DRAWONLYFORP2; - - if (mobj->target->eflags & MFE_DRAWONLYFORP3) - mobj->eflags |= MFE_DRAWONLYFORP3; - else - mobj->eflags &= ~MFE_DRAWONLYFORP3; - - if (mobj->target->eflags & MFE_DRAWONLYFORP4) - mobj->eflags |= MFE_DRAWONLYFORP4; - else - mobj->eflags &= ~MFE_DRAWONLYFORP4; - - if (mobj->target->flags2 & MF2_DONTDRAW) - mobj->flags2 |= MF2_DONTDRAW; - else - mobj->flags2 &= ~MF2_DONTDRAW; - - if (mobj->target->eflags & MFE_VERTICALFLIP) - offz += 4*FRACUNIT; - else - offz -= 4*FRACUNIT; - - if (mobj->tracer && mobj->tracer->player && mobj->tracer->player->mo - && mobj->tracer->player->health > 0 && !mobj->tracer->player->spectator) // STOLEN - mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen bumpers - else - mobj->color = mobj->target->color; // but do so if it belongs to you :B - - if (mobj->target->player->kartstuff[k_bumper] < 2) - P_SetMobjState(mobj, S_BATTLEBUMPER3); - else if (mobj->target->player->kartstuff[k_bumper] < 3) - P_SetMobjState(mobj, S_BATTLEBUMPER2); - else - P_SetMobjState(mobj, S_BATTLEBUMPER1); - - // Shrink your items if the player shrunk too. - mobj->scale = mobj->target->scale; - - P_UnsetThingPosition(mobj); - { - const angle_t fa = ang>>ANGLETOFINESHIFT; - mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa), rad); - mobj->y = mobj->target->y + FixedMul(FINESINE(fa), rad); - mobj->z = mobj->target->z + offz; - P_SetThingPosition(mobj); - } - - // Was this so hard? - if (mobj->target->player->kartstuff[k_bumper] <= mobj->threshold) - { - P_RemoveMobj(mobj); - return; - } - } - else if ((mobj->health > 0 - && (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->player->health <= 0 || mobj->target->player->spectator)) - || (mobj->health <= 0 && P_IsObjectOnGround(mobj)) - || P_CheckDeathPitCollide(mobj)) // When in death state - { - P_RemoveMobj(mobj); - return; - } - break; - case MT_PLAYERARROW: - if (mobj->target && mobj->target->health - && mobj->target->player && !mobj->target->player->spectator - && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD - /*&& players[displayplayers[0]].mo && !players[displayplayers[0]].spectator*/) - { - fixed_t scale = 3*mobj->target->scale; - mobj->color = mobj->target->color; - K_MatchGenericExtraFlags(mobj, mobj->target); - - if ((G_RaceGametype() || mobj->target->player->kartstuff[k_bumper] <= 0) -#if 1 // Set to 0 to test without needing to host - || ((mobj->target->player == &players[displayplayers[0]]) || P_IsLocalPlayer(mobj->target->player)) -#endif - ) - mobj->flags2 |= MF2_DONTDRAW; - - P_UnsetThingPosition(mobj); - mobj->x = mobj->target->x; - mobj->y = mobj->target->y; - - mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's - - if (!splitscreen && players[displayplayers[0]].mo) - { - scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x, - players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); - if (scale > 16*mobj->target->scale) - scale = 16*mobj->target->scale; - } - mobj->destscale = scale; - - if (!(mobj->target->eflags & MFE_VERTICALFLIP)) - { - mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player) + (16*mobj->target->scale); - mobj->eflags &= ~MFE_VERTICALFLIP; - } - else - { - mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player) - (16*mobj->target->scale); - mobj->eflags |= MFE_VERTICALFLIP; - } - P_SetThingPosition(mobj); - - if (!mobj->tracer) - { - mobj_t *overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); - P_SetTarget(&mobj->tracer, overlay); - P_SetTarget(&mobj->tracer->target, mobj); - P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM); - P_SetScale(mobj->tracer, (mobj->tracer->destscale = mobj->scale)); - } - - // Do this in an easy way - if (mobj->target->player->kartstuff[k_itemroulette]) - { - mobj->tracer->color = mobj->target->player->skincolor; - mobj->tracer->colorized = true; - } - else - { - mobj->tracer->color = SKINCOLOR_NONE; - mobj->tracer->colorized = false; - } - - if (!(mobj->flags2 & MF2_DONTDRAW)) - { - const INT32 numberdisplaymin = ((mobj->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) ? 5 : 2); - - // Set it to use the correct states for its condition - if (mobj->target->player->kartstuff[k_itemroulette]) - { - P_SetMobjState(mobj, S_PLAYERARROW_BOX); - mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|(((mobj->target->player->kartstuff[k_itemroulette] % (13*3)) / 3) + 1); - mobj->tracer->flags2 &= ~MF2_DONTDRAW; - } - else if (mobj->target->player->kartstuff[k_stolentimer] > 0) - { - P_SetMobjState(mobj, S_PLAYERARROW_BOX); - mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO; - if (leveltime & 2) - mobj->tracer->flags2 &= ~MF2_DONTDRAW; - else - mobj->tracer->flags2 |= MF2_DONTDRAW; - } - else if ((mobj->target->player->kartstuff[k_stealingtimer] > 0) && (leveltime & 2)) - { - P_SetMobjState(mobj, S_PLAYERARROW_BOX); - mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO; - mobj->tracer->flags2 &= ~MF2_DONTDRAW; - } - else if (mobj->target->player->kartstuff[k_eggmanexplode] > 1) - { - P_SetMobjState(mobj, S_PLAYERARROW_BOX); - mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|KITEM_EGGMAN; - if (leveltime & 1) - mobj->tracer->flags2 &= ~MF2_DONTDRAW; - else - mobj->tracer->flags2 |= MF2_DONTDRAW; - } - else if (mobj->target->player->kartstuff[k_rocketsneakertimer] > 1) - { - //itembar = mobj->target->player->kartstuff[k_rocketsneakertimer]; -- not today satan - P_SetMobjState(mobj, S_PLAYERARROW_BOX); - mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|KITEM_ROCKETSNEAKER; - if (leveltime & 1) - mobj->tracer->flags2 &= ~MF2_DONTDRAW; - else - mobj->tracer->flags2 |= MF2_DONTDRAW; - } - else if (mobj->target->player->kartstuff[k_growshrinktimer] > 0) - { - P_SetMobjState(mobj, S_PLAYERARROW_BOX); - mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|KITEM_GROW; - - if (leveltime & 1) - mobj->tracer->flags2 &= ~MF2_DONTDRAW; - else - mobj->tracer->flags2 |= MF2_DONTDRAW; - } - else if (mobj->target->player->kartstuff[k_itemtype] && mobj->target->player->kartstuff[k_itemamount] > 0) - { - P_SetMobjState(mobj, S_PLAYERARROW_BOX); - - switch (mobj->target->player->kartstuff[k_itemtype]) - { - case KITEM_ORBINAUT: - mobj->tracer->sprite = SPR_ITMO; - mobj->tracer->frame = FF_FULLBRIGHT|(min(mobj->target->player->kartstuff[k_itemamount]-1, 3)); - break; - case KITEM_INVINCIBILITY: - mobj->tracer->sprite = SPR_ITMI; - mobj->tracer->frame = FF_FULLBRIGHT|((leveltime % (7*3)) / 3); - break; - case KITEM_SAD: - mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT; - break; - default: - mobj->tracer->sprite = SPR_ITEM; - mobj->tracer->frame = FF_FULLBRIGHT|(mobj->target->player->kartstuff[k_itemtype]); - break; - } - - if (mobj->target->player->kartstuff[k_itemheld]) - { - if (leveltime & 1) - mobj->tracer->flags2 &= ~MF2_DONTDRAW; - else - mobj->tracer->flags2 |= MF2_DONTDRAW; - } - else - mobj->tracer->flags2 &= ~MF2_DONTDRAW; - } - else - { - P_SetMobjState(mobj, S_PLAYERARROW); - P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM); - } - - mobj->tracer->destscale = scale; - - if (mobj->target->player->kartstuff[k_itemamount] >= numberdisplaymin - && mobj->target->player->kartstuff[k_itemamount] <= 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V - { - mobj_t *number = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); - mobj_t *numx = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); - - P_SetTarget(&number->target, mobj); - P_SetMobjState(number, S_PLAYERARROW_NUMBER); - P_SetScale(number, mobj->scale); - number->destscale = scale; - number->frame = FF_FULLBRIGHT|(mobj->target->player->kartstuff[k_itemamount]); - - P_SetTarget(&numx->target, mobj); - P_SetMobjState(numx, S_PLAYERARROW_X); - P_SetScale(numx, mobj->scale); - numx->destscale = scale; - } - - if (K_IsPlayerWanted(mobj->target->player) && mobj->movecount != 1) - { - mobj_t *wanted = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PLAYERWANTED); - P_SetTarget(&wanted->target, mobj->target); - P_SetTarget(&wanted->tracer, mobj); - P_SetScale(wanted, mobj->scale); - wanted->destscale = scale; - mobj->movecount = 1; - } - else if (!K_IsPlayerWanted(mobj->target->player)) - mobj->movecount = 0; - } - else - mobj->tracer->flags2 |= MF2_DONTDRAW; - } - else if (mobj->health > 0) - { - P_KillMobj(mobj, NULL, NULL); - return; - } - break; - case MT_PLAYERWANTED: - if (mobj->target && mobj->target->health && mobj->tracer - && mobj->target->player && !mobj->target->player->spectator - && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD - && players[displayplayers[0]].mo && !players[displayplayers[0]].spectator) - { - fixed_t scale = 3*mobj->target->scale; - - if (!K_IsPlayerWanted(mobj->target->player)) - { - mobj->tracer->movecount = 0; - P_RemoveMobj(mobj); - return; - } - - if (mobj->tracer->flags2 & MF2_DONTDRAW) - mobj->flags2 |= MF2_DONTDRAW; - else - mobj->flags2 &= ~MF2_DONTDRAW; - - P_UnsetThingPosition(mobj); - mobj->x = mobj->target->x; - mobj->y = mobj->target->y; - - if (!splitscreen) - { - scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x, - players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); - if (scale > 16*mobj->target->scale) - scale = 16*mobj->target->scale; - } - mobj->destscale = scale; - - if (!(mobj->target->eflags & MFE_VERTICALFLIP)) - { - mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)) + (16*mobj->target->scale) + (64*scale); - mobj->eflags &= ~MFE_VERTICALFLIP; - } - else - { - mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)) - (16*mobj->target->scale) - (64*scale); - mobj->eflags |= MFE_VERTICALFLIP; - } - P_SetThingPosition(mobj); - } - else if (mobj->health > 0) - { - P_KillMobj(mobj, NULL, NULL); - return; - } - break; - case MT_PETSMOKER: - if (!(leveltime % 10)) - { - mobj_t *smok = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PETSMOKE); - if (mobj->spawnpoint && mobj->spawnpoint->options & MTF_OBJECTSPECIAL) - P_SetMobjStateNF(smok, smok->info->painstate); // same function, diff sprite - } - break; - //} - case MT_WATERDROP: - P_SceneryCheckWater(mobj); - if ((mobj->z <= mobj->floorz || mobj->z <= mobj->watertop) - && mobj->health > 0) - { - mobj->health = 0; - P_SetMobjState(mobj, mobj->info->deathstate); - S_StartSound(mobj, mobj->info->deathsound+P_RandomKey(mobj->info->mass)); - return; - } - break; - case MT_BUBBLES: - P_SceneryCheckWater(mobj); - break; - case MT_SMALLBUBBLE: - case MT_MEDIUMBUBBLE: - case MT_EXTRALARGEBUBBLE: // start bubble dissipate - P_SceneryCheckWater(mobj); - if (P_MobjWasRemoved(mobj)) // bubble was removed by not being in water - return; - if (!(mobj->eflags & MFE_UNDERWATER) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height >= mobj->ceilingz) - || (mobj->eflags & MFE_VERTICALFLIP && mobj->z <= mobj->floorz) - || (P_CheckDeathPitCollide(mobj)) - || --mobj->fuse <= 0) // Bubbles eventually dissipate if they can't reach the surface. - { - // no playing sound: no point; the object is being removed - P_RemoveMobj(mobj); - return; - } - break; - case MT_DROWNNUMBERS: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return; - } - if (!mobj->target->player || !(mobj->target->player->powers[pw_underwater] || mobj->target->player->powers[pw_spacetime])) - { - P_RemoveMobj(mobj); - return; - } - mobj->x = mobj->target->x; - mobj->y = mobj->target->y; - - mobj->destscale = mobj->target->destscale; - P_SetScale(mobj, mobj->target->scale); + ang = (ang*leveltime) + (diff * (mobj->threshold-1)); + // If the player is on the ceiling, then flip your items as well. if (mobj->target->eflags & MFE_VERTICALFLIP) { - mobj->z = mobj->target->z - FixedMul(16*FRACUNIT, mobj->target->scale) - mobj->height; - if (mobj->target->player->pflags & PF_FLIPCAM) - mobj->eflags |= MFE_VERTICALFLIP; + mobj->eflags |= MFE_VERTICALFLIP; + offz = mobj->target->height / 2; } else - mobj->z = mobj->target->z + (mobj->target->height) + FixedMul(8*FRACUNIT, mobj->target->scale); // Adjust height for height changes + { + mobj->eflags &= ~MFE_VERTICALFLIP; + offz = mobj->target->height / 5; + } - if (mobj->threshold <= 35) + if (mobj->target->eflags & MFE_DRAWONLYFORP1) // groooooaann... + mobj->eflags |= MFE_DRAWONLYFORP1; + else + mobj->eflags &= ~MFE_DRAWONLYFORP1; + + if (mobj->target->eflags & MFE_DRAWONLYFORP2) + mobj->eflags |= MFE_DRAWONLYFORP2; + else + mobj->eflags &= ~MFE_DRAWONLYFORP2; + + if (mobj->target->eflags & MFE_DRAWONLYFORP3) + mobj->eflags |= MFE_DRAWONLYFORP3; + else + mobj->eflags &= ~MFE_DRAWONLYFORP3; + + if (mobj->target->eflags & MFE_DRAWONLYFORP4) + mobj->eflags |= MFE_DRAWONLYFORP4; + else + mobj->eflags &= ~MFE_DRAWONLYFORP4; + + if (mobj->target->flags2 & MF2_DONTDRAW) mobj->flags2 |= MF2_DONTDRAW; else mobj->flags2 &= ~MF2_DONTDRAW; - if (mobj->threshold <= 30) - mobj->threshold = 40; - mobj->threshold--; - break; - case MT_FLAMEJET: - if ((mobj->flags2 & MF2_FIRING) && (leveltime & 3) == 0) + + if (mobj->target->eflags & MFE_VERTICALFLIP) + offz += 4*FRACUNIT; + else + offz -= 4*FRACUNIT; + + if (mobj->tracer && mobj->tracer->player && mobj->tracer->player->mo + && mobj->tracer->player->health > 0 && !mobj->tracer->player->spectator) // STOLEN + mobj->color = mobj->tracer->player->skincolor; // don't do star flashing for stolen bumpers + else + mobj->color = mobj->target->color; // but do so if it belongs to you :B + + if (mobj->target->player->kartstuff[k_bumper] < 2) + P_SetMobjState(mobj, S_BATTLEBUMPER3); + else if (mobj->target->player->kartstuff[k_bumper] < 3) + P_SetMobjState(mobj, S_BATTLEBUMPER2); + else + P_SetMobjState(mobj, S_BATTLEBUMPER1); + + // Shrink your items if the player shrunk too. + mobj->scale = mobj->target->scale; + + P_UnsetThingPosition(mobj); { - mobj_t *flame; - fixed_t strength; - - // Wave the flames back and forth. Reactiontime determines which direction it's going. - if (mobj->fuse <= -16) - mobj->reactiontime = 1; - else if (mobj->fuse >= 16) - mobj->reactiontime = 0; - - if (mobj->reactiontime) - mobj->fuse += 2; - else - mobj->fuse -= 2; - - flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); - - flame->angle = mobj->angle; - - if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side - flame->momz = mobj->fuse << (FRACBITS-2); - else - flame->angle += FixedAngle(mobj->fuse*FRACUNIT); - - strength = 20*FRACUNIT; - strength -= ((20*FRACUNIT)/16)*mobj->movedir; - - P_InstaThrust(flame, flame->angle, strength); - S_StartSound(flame, sfx_fire); + const angle_t fa = ang>>ANGLETOFINESHIFT; + mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa), rad); + mobj->y = mobj->target->y + FixedMul(FINESINE(fa), rad); + mobj->z = mobj->target->z + offz; + P_SetThingPosition(mobj); } - break; - case MT_VERTICALFLAMEJET: - if ((mobj->flags2 & MF2_FIRING) && (leveltime & 3) == 0) + + // Was this so hard? + if (mobj->target->player->kartstuff[k_bumper] <= mobj->threshold) { - mobj_t *flame; - fixed_t strength; - - // Wave the flames back and forth. Reactiontime determines which direction it's going. - if (mobj->fuse <= -16) - mobj->reactiontime = 1; - else if (mobj->fuse >= 16) - mobj->reactiontime = 0; - - if (mobj->reactiontime) - mobj->fuse++; - else - mobj->fuse--; - - flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); - - strength = 20*FRACUNIT; - strength -= ((20*FRACUNIT)/16)*mobj->movedir; - - // If deaf'd, the object spawns on the ceiling. - if (mobj->flags2 & MF2_AMBUSH) - { - mobj->z = mobj->ceilingz-mobj->height; - flame->momz = -strength; - } - else - flame->momz = strength; - P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT,3*FRACUNIT)); - S_StartSound(flame, sfx_fire); - } - break; - case MT_SEED: - mobj->momz = mobj->info->speed; - break; - case MT_ROCKCRUMBLE1: - case MT_ROCKCRUMBLE2: - case MT_ROCKCRUMBLE3: - case MT_ROCKCRUMBLE4: - case MT_ROCKCRUMBLE5: - case MT_ROCKCRUMBLE6: - case MT_ROCKCRUMBLE7: - case MT_ROCKCRUMBLE8: - case MT_ROCKCRUMBLE9: - case MT_ROCKCRUMBLE10: - case MT_ROCKCRUMBLE11: - case MT_ROCKCRUMBLE12: - case MT_ROCKCRUMBLE13: - case MT_ROCKCRUMBLE14: - case MT_ROCKCRUMBLE15: - case MT_ROCKCRUMBLE16: - if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) - && mobj->state != &states[mobj->info->deathstate]) - { - P_SetMobjState(mobj, mobj->info->deathstate); + P_RemoveMobj(mobj); return; } - break; - case MT_FIREDITEM: - if (mobj->target && !P_MobjWasRemoved(mobj->target)) + } + else if ((mobj->health > 0 + && (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->player->health <= 0 || mobj->target->player->spectator)) + || (mobj->health <= 0 && P_IsObjectOnGround(mobj)) + || P_CheckDeathPitCollide(mobj)) // When in death state + { + P_RemoveMobj(mobj); + return; + } + break; + case MT_PLAYERARROW: + if (mobj->target && mobj->target->health + && mobj->target->player && !mobj->target->player->spectator + && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD + /*&& players[displayplayers[0]].mo && !players[displayplayers[0]].spectator*/) + { + fixed_t scale = 3*mobj->target->scale; + mobj->color = mobj->target->color; + K_MatchGenericExtraFlags(mobj, mobj->target); + + if ((G_RaceGametype() || mobj->target->player->kartstuff[k_bumper] <= 0) +#if 1 // Set to 0 to test without needing to host + || ((mobj->target->player == &players[displayplayers[0]]) || P_IsLocalPlayer(mobj->target->player)) +#endif + ) + mobj->flags2 |= MF2_DONTDRAW; + + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's + + if (!splitscreen && players[displayplayers[0]].mo) { - fixed_t x, y, z; - if (mobj->movecount) + scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x, + players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); + if (scale > 16*mobj->target->scale) + scale = 16*mobj->target->scale; + } + mobj->destscale = scale; + + if (!(mobj->target->eflags & MFE_VERTICALFLIP)) + { + mobj->z = mobj->target->z + P_GetPlayerHeight(mobj->target->player) + (16*mobj->target->scale); + mobj->eflags &= ~MFE_VERTICALFLIP; + } + else + { + mobj->z = mobj->target->z - P_GetPlayerHeight(mobj->target->player) - (16*mobj->target->scale); + mobj->eflags |= MFE_VERTICALFLIP; + } + P_SetThingPosition(mobj); + + if (!mobj->tracer) + { + mobj_t *overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + P_SetTarget(&mobj->tracer, overlay); + P_SetTarget(&mobj->tracer->target, mobj); + P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM); + P_SetScale(mobj->tracer, (mobj->tracer->destscale = mobj->scale)); + } + + // Do this in an easy way + if (mobj->target->player->kartstuff[k_itemroulette]) + { + mobj->tracer->color = mobj->target->player->skincolor; + mobj->tracer->colorized = true; + } + else + { + mobj->tracer->color = SKINCOLOR_NONE; + mobj->tracer->colorized = false; + } + + if (!(mobj->flags2 & MF2_DONTDRAW)) + { + const INT32 numberdisplaymin = ((mobj->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) ? 5 : 2); + + // Set it to use the correct states for its condition + if (mobj->target->player->kartstuff[k_itemroulette]) { - x = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle + mobj->movedir, mobj->target->radius + mobj->radius); - y = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle + mobj->movedir, mobj->target->radius + mobj->radius); - z = mobj->target->z + mobj->target->height/3; + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|(((mobj->target->player->kartstuff[k_itemroulette] % (13*3)) / 3) + 1); + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + } + else if (mobj->target->player->kartstuff[k_stolentimer] > 0) + { + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO; + if (leveltime & 2) + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + else + mobj->tracer->flags2 |= MF2_DONTDRAW; + } + else if ((mobj->target->player->kartstuff[k_stealingtimer] > 0) && (leveltime & 2)) + { + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO; + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + } + else if (mobj->target->player->kartstuff[k_eggmanexplode] > 1) + { + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|KITEM_EGGMAN; + if (leveltime & 1) + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + else + mobj->tracer->flags2 |= MF2_DONTDRAW; + } + else if (mobj->target->player->kartstuff[k_rocketsneakertimer] > 1) + { + //itembar = mobj->target->player->kartstuff[k_rocketsneakertimer]; -- not today satan + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|KITEM_ROCKETSNEAKER; + if (leveltime & 1) + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + else + mobj->tracer->flags2 |= MF2_DONTDRAW; + } + else if (mobj->target->player->kartstuff[k_growshrinktimer] > 0) + { + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|KITEM_GROW; + + if (leveltime & 1) + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + else + mobj->tracer->flags2 |= MF2_DONTDRAW; + } + else if (mobj->target->player->kartstuff[k_itemtype] && mobj->target->player->kartstuff[k_itemamount] > 0) + { + P_SetMobjState(mobj, S_PLAYERARROW_BOX); + + switch (mobj->target->player->kartstuff[k_itemtype]) + { + case KITEM_ORBINAUT: + mobj->tracer->sprite = SPR_ITMO; + mobj->tracer->frame = FF_FULLBRIGHT|(min(mobj->target->player->kartstuff[k_itemamount]-1, 3)); + break; + case KITEM_INVINCIBILITY: + mobj->tracer->sprite = SPR_ITMI; + mobj->tracer->frame = FF_FULLBRIGHT|((leveltime % (7*3)) / 3); + break; + case KITEM_SAD: + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT; + break; + default: + mobj->tracer->sprite = SPR_ITEM; + mobj->tracer->frame = FF_FULLBRIGHT|(mobj->target->player->kartstuff[k_itemtype]); + break; + } + + if (mobj->target->player->kartstuff[k_itemheld]) + { + if (leveltime & 1) + mobj->tracer->flags2 &= ~MF2_DONTDRAW; + else + mobj->tracer->flags2 |= MF2_DONTDRAW; + } + else + mobj->tracer->flags2 &= ~MF2_DONTDRAW; } else { - x = mobj->target->x; - y = mobj->target->y; - z = mobj->target->z + (80*mapobjectscale); + P_SetMobjState(mobj, S_PLAYERARROW); + P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM); } - if (mobj->target->eflags & MFE_VERTICALFLIP) - z += mobj->target->height - FixedMul(mobj->target->scale, mobj->height); - P_MoveOrigin(mobj, x, y, z); - } - break; - default: - if (mobj->fuse) - { // Scenery object fuse! Very basic! - mobj->fuse--; - if (!mobj->fuse) + mobj->tracer->destscale = scale; + + if (mobj->target->player->kartstuff[k_itemamount] >= numberdisplaymin + && mobj->target->player->kartstuff[k_itemamount] <= 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V { - if (!LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse))) - P_RemoveMobj(mobj); - return; + mobj_t *number = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + mobj_t *numx = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); + + P_SetTarget(&number->target, mobj); + P_SetMobjState(number, S_PLAYERARROW_NUMBER); + P_SetScale(number, mobj->scale); + number->destscale = scale; + number->frame = FF_FULLBRIGHT|(mobj->target->player->kartstuff[k_itemamount]); + + P_SetTarget(&numx->target, mobj); + P_SetMobjState(numx, S_PLAYERARROW_X); + P_SetScale(numx, mobj->scale); + numx->destscale = scale; } + + if (K_IsPlayerWanted(mobj->target->player) && mobj->movecount != 1) + { + mobj_t *wanted = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PLAYERWANTED); + P_SetTarget(&wanted->target, mobj->target); + P_SetTarget(&wanted->tracer, mobj); + P_SetScale(wanted, mobj->scale); + wanted->destscale = scale; + mobj->movecount = 1; + } + else if (!K_IsPlayerWanted(mobj->target->player)) + mobj->movecount = 0; } - break; - } - - P_SceneryThinker(mobj); - return; - } - - // Check for a Lua thinker first - if (!mobj->player) - { - if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker)) || P_MobjWasRemoved(mobj)) - return; - } - else if (!mobj->player->spectator) - { - // You cannot short-circuit the player thinker like you can other thinkers. - LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker)); - if (P_MobjWasRemoved(mobj)) - return; - } - - // if it's pushable, or if it would be pushable other than temporary disablement, use the - // separate thinker - if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse)) - { - if (!mobj) - return; - - P_MobjCheckWater(mobj); - P_PushableThinker(mobj); - - // Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.) - if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL - && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) - { - P_KillMobj(mobj, NULL, NULL); - return; - } - } - else if (mobj->flags & MF_BOSS) - { - if (LUA_HookMobj(mobj, MOBJ_HOOK(BossThinker))) - { - if (P_MobjWasRemoved(mobj)) + else + mobj->tracer->flags2 |= MF2_DONTDRAW; + } + else if (mobj->health > 0) + { + P_KillMobj(mobj, NULL, NULL); return; - } - else if (P_MobjWasRemoved(mobj)) - return; - else - switch (mobj->type) - { - case MT_EGGMOBILE: - if (mobj->health < mobj->info->damage+1 && leveltime & 1 && mobj->health > 0) - P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMOKE); - if (mobj->flags2 & MF2_SKULLFLY) - P_SpawnGhostMobj(mobj); - P_Boss1Thinker(mobj); - break; - case MT_EGGMOBILE2: - P_Boss2Thinker(mobj); - break; - case MT_EGGMOBILE3: - P_Boss3Thinker(mobj); - break; - case MT_EGGMOBILE4: - P_Boss4Thinker(mobj); - break; - case MT_BLACKEGGMAN: - P_Boss7Thinker(mobj); - break; - case MT_METALSONIC_BATTLE: - P_Boss9Thinker(mobj); - break; - default: // Generic SOC-made boss - if (mobj->flags2 & MF2_SKULLFLY) - P_SpawnGhostMobj(mobj); - P_GenericBossThinker(mobj); - break; - } - if (mobj->flags2 & MF2_BOSSFLEE) - P_InstaThrust(mobj, mobj->angle, FixedMul(12*FRACUNIT, mobj->scale)); + } + break; + case MT_PLAYERWANTED: + if (mobj->target && mobj->target->health && mobj->tracer + && mobj->target->player && !mobj->target->player->spectator + && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD + && players[displayplayers[0]].mo && !players[displayplayers[0]].spectator) + { + fixed_t scale = 3*mobj->target->scale; + + if (!K_IsPlayerWanted(mobj->target->player)) + { + mobj->tracer->movecount = 0; + P_RemoveMobj(mobj); + return; + } + + if (mobj->tracer->flags2 & MF2_DONTDRAW) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + if (!splitscreen) + { + scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x, + players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); + if (scale > 16*mobj->target->scale) + scale = 16*mobj->target->scale; + } + mobj->destscale = scale; + + if (!(mobj->target->eflags & MFE_VERTICALFLIP)) + { + mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)) + (16*mobj->target->scale) + (64*scale); + mobj->eflags &= ~MFE_VERTICALFLIP; + } + else + { + mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)) - (16*mobj->target->scale) - (64*scale); + mobj->eflags |= MFE_VERTICALFLIP; + } + P_SetThingPosition(mobj); + } + else if (mobj->health > 0) + { + P_KillMobj(mobj, NULL, NULL); + return; + } + break; + case MT_PETSMOKER: + if (!(leveltime % 10)) + { + mobj_t *smok = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PETSMOKE); + if (mobj->spawnpoint && mobj->spawnpoint->options & MTF_OBJECTSPECIAL) + P_SetMobjStateNF(smok, smok->info->painstate); // same function, diff sprite + } + break; + //} + case MT_WATERDROP: + P_SceneryCheckWater(mobj); + if ((mobj->z <= mobj->floorz || mobj->z <= mobj->watertop) + && mobj->health > 0) + { + mobj->health = 0; + P_SetMobjState(mobj, mobj->info->deathstate); + S_StartSound(mobj, mobj->info->deathsound+P_RandomKey(mobj->info->mass)); + return; + } + break; + case MT_BUBBLES: + P_SceneryCheckWater(mobj); + break; + case MT_SMALLBUBBLE: + case MT_MEDIUMBUBBLE: + case MT_EXTRALARGEBUBBLE: // start bubble dissipate + P_SceneryCheckWater(mobj); + if (P_MobjWasRemoved(mobj)) // bubble was removed by not being in water + return; + if (!(mobj->eflags & MFE_UNDERWATER) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height >= mobj->ceilingz) + || (mobj->eflags & MFE_VERTICALFLIP && mobj->z <= mobj->floorz) + || (P_CheckDeathPitCollide(mobj)) + || --mobj->fuse <= 0) // Bubbles eventually dissipate if they can't reach the surface. + { + // no playing sound: no point; the object is being removed + P_RemoveMobj(mobj); + return; + } + break; + case MT_DROWNNUMBERS: + if (!mobj->target) + { + P_RemoveMobj(mobj); + return; + } + if (!mobj->target->player || !(mobj->target->player->powers[pw_underwater] || mobj->target->player->powers[pw_spacetime])) + { + P_RemoveMobj(mobj); + return; + } + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + mobj->destscale = mobj->target->destscale; + P_SetScale(mobj, mobj->target->scale); + + if (mobj->target->eflags & MFE_VERTICALFLIP) + { + mobj->z = mobj->target->z - FixedMul(16*FRACUNIT, mobj->target->scale) - mobj->height; + if (mobj->target->player->pflags & PF_FLIPCAM) + mobj->eflags |= MFE_VERTICALFLIP; + } + else + mobj->z = mobj->target->z + (mobj->target->height) + FixedMul(8*FRACUNIT, mobj->target->scale); // Adjust height for height changes + + if (mobj->threshold <= 35) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + if (mobj->threshold <= 30) + mobj->threshold = 40; + mobj->threshold--; + break; + case MT_FLAMEJET: + if ((mobj->flags2 & MF2_FIRING) && (leveltime & 3) == 0) + { + mobj_t *flame; + fixed_t strength; + + // Wave the flames back and forth. Reactiontime determines which direction it's going. + if (mobj->fuse <= -16) + mobj->reactiontime = 1; + else if (mobj->fuse >= 16) + mobj->reactiontime = 0; + + if (mobj->reactiontime) + mobj->fuse += 2; + else + mobj->fuse -= 2; + + flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); + + flame->angle = mobj->angle; + + if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side + flame->momz = mobj->fuse << (FRACBITS-2); + else + flame->angle += FixedAngle(mobj->fuse*FRACUNIT); + + strength = 20*FRACUNIT; + strength -= ((20*FRACUNIT)/16)*mobj->movedir; + + P_InstaThrust(flame, flame->angle, strength); + S_StartSound(flame, sfx_fire); + } + break; + case MT_VERTICALFLAMEJET: + if ((mobj->flags2 & MF2_FIRING) && (leveltime & 3) == 0) + { + mobj_t *flame; + fixed_t strength; + + // Wave the flames back and forth. Reactiontime determines which direction it's going. + if (mobj->fuse <= -16) + mobj->reactiontime = 1; + else if (mobj->fuse >= 16) + mobj->reactiontime = 0; + + if (mobj->reactiontime) + mobj->fuse++; + else + mobj->fuse--; + + flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); + + strength = 20*FRACUNIT; + strength -= ((20*FRACUNIT)/16)*mobj->movedir; + + // If deaf'd, the object spawns on the ceiling. + if (mobj->flags2 & MF2_AMBUSH) + { + mobj->z = mobj->ceilingz-mobj->height; + flame->momz = -strength; + } + else + flame->momz = strength; + P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT,3*FRACUNIT)); + S_StartSound(flame, sfx_fire); + } + break; + case MT_SEED: + mobj->momz = mobj->info->speed; + break; + case MT_ROCKCRUMBLE1: + case MT_ROCKCRUMBLE2: + case MT_ROCKCRUMBLE3: + case MT_ROCKCRUMBLE4: + case MT_ROCKCRUMBLE5: + case MT_ROCKCRUMBLE6: + case MT_ROCKCRUMBLE7: + case MT_ROCKCRUMBLE8: + case MT_ROCKCRUMBLE9: + case MT_ROCKCRUMBLE10: + case MT_ROCKCRUMBLE11: + case MT_ROCKCRUMBLE12: + case MT_ROCKCRUMBLE13: + case MT_ROCKCRUMBLE14: + case MT_ROCKCRUMBLE15: + case MT_ROCKCRUMBLE16: + if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) + && mobj->state != &states[mobj->info->deathstate]) + { + P_SetMobjState(mobj, mobj->info->deathstate); + return; + } + break; + case MT_FIREDITEM: + if (mobj->target && !P_MobjWasRemoved(mobj->target)) + { + fixed_t x, y, z; + if (mobj->movecount) + { + x = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle + mobj->movedir, mobj->target->radius + mobj->radius); + y = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle + mobj->movedir, mobj->target->radius + mobj->radius); + z = mobj->target->z + mobj->target->height/3; + } + else + { + x = mobj->target->x; + y = mobj->target->y; + z = mobj->target->z + (80*mapobjectscale); + } + if (mobj->target->eflags & MFE_VERTICALFLIP) + z += mobj->target->height - FixedMul(mobj->target->scale, mobj->height); + + P_MoveOrigin(mobj, x, y, z); + } + break; + default: + if (mobj->fuse) + { // Scenery object fuse! Very basic! + mobj->fuse--; + if (!mobj->fuse) + { + if (!LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse))) + P_RemoveMobj(mobj); + return; + } + } + break; } - else if (mobj->health <= 0) // Dead things think differently than the living. - switch (mobj->type) - { + + P_SceneryThinker(mobj); +} + +static boolean P_MobjBossThink(mobj_t *mobj) +{ + if (LUA_HookMobj(mobj, MOBJ_HOOK(BossThinker))) + { + if (P_MobjWasRemoved(mobj)) + return false; + } + + if (P_MobjWasRemoved(mobj)) + return false; + + switch (mobj->type) + { + case MT_EGGMOBILE: + if (mobj->health < mobj->info->damage+1 && leveltime & 1 && mobj->health > 0) + P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMOKE); + if (mobj->flags2 & MF2_SKULLFLY) + P_SpawnGhostMobj(mobj); + P_Boss1Thinker(mobj); + break; + case MT_EGGMOBILE2: + P_Boss2Thinker(mobj); + break; + case MT_EGGMOBILE3: + P_Boss3Thinker(mobj); + break; + case MT_EGGMOBILE4: + P_Boss4Thinker(mobj); + break; + case MT_BLACKEGGMAN: + P_Boss7Thinker(mobj); + break; + case MT_METALSONIC_BATTLE: + P_Boss9Thinker(mobj); + break; + default: // Generic SOC-made boss + if (mobj->flags2 & MF2_SKULLFLY) + P_SpawnGhostMobj(mobj); + P_GenericBossThinker(mobj); + break; + } + + if (mobj->flags2 & MF2_BOSSFLEE) + P_InstaThrust(mobj, mobj->angle, FixedMul(12*FRACUNIT, mobj->scale)); + + return true; +} + +static boolean P_MobjDeadThink(mobj_t *mobj) +{ + switch (mobj->type) + { case MT_BLUEBALL: if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<z <= mobj->floorz) { P_RemoveMobj(mobj); - return; + return false; } break; case MT_EGGTRAP: // Egg Capsule animal release @@ -6992,7 +6887,7 @@ void P_MobjThinker(mobj_t *mobj) else // safe to remove, nobody's going to complain! { P_RemoveMobj(mobj); - return; + return false; } } else // Apply gravity to fall downwards. @@ -7003,18 +6898,15 @@ void P_MobjThinker(mobj_t *mobj) } } break; - //{ SRB2kart Items - Death States + //{ SRB2kart Items - Death States case MT_BANANA: if (cv_bananthrowroll.value) { //mobj->angle -= spin; - if (cv_bananthrowroll.value == 1 && K_CheckSlopeRollDist(mobj)) mobj->sloperoll += (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h); // im lazy but this makes sure the banan goes back to upright when it lands lmao else if (cv_bananthrowroll.value == 2) mobj->rollangle += (angle_t)FixedMul(FixedDiv(abs(mobj->momz), 8 * mobj->scale), ANGLE_67h); - - //if (P_IsObjectOnGround(mobj) && mobj->momz * P_MobjFlip(mobj) <= 0) } /* FALLTHRU */ case MT_ORBINAUT: @@ -7023,7 +6915,7 @@ void P_MobjThinker(mobj_t *mobj) if (P_IsObjectOnGround(mobj)) { P_RemoveMobj(mobj); - return; + return false; } // fallthru case MT_ORBINAUT_SHIELD: @@ -7035,7 +6927,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_JAWZ_DUD: if (P_IsObjectOnGround(mobj)) P_SetMobjState(mobj, mobj->info->xdeathstate); - // fallthru + // fallthru case MT_JAWZ_SHIELD: mobj->flags2 ^= MF2_DONTDRAW; break; @@ -7049,12 +6941,12 @@ void P_MobjThinker(mobj_t *mobj) else { P_RemoveMobj(mobj); - return; + return false; } break; case MT_MINEEXPLOSIONSOUND: P_RemoveMobj(mobj); - return; + return false; case MT_CDUFO: if (mobj->fuse > TICRATE) mobj->flags2 ^= MF2_DONTDRAW; // only by good fortune does this end with it having MF2_DONTDRAW... don't touch! @@ -7064,13 +6956,13 @@ void P_MobjThinker(mobj_t *mobj) P_SetMobjStateNF(mobj, mobj->info->seestate); else P_SetMobjStateNF(mobj, mobj->info->spawnstate); - /* FALLTHRU */ + /* FALLTHRU */ case MT_SMK_MOLE: mobj->flags2 ^= MF2_DONTDRAW; if (P_IsObjectOnGround(mobj)) { P_RemoveMobj(mobj); - return; + return false; } break; case MT_SMK_THWOMP: @@ -7091,14 +6983,20 @@ void P_MobjThinker(mobj_t *mobj) if (P_IsObjectOnGround(mobj)) { P_RemoveMobj(mobj); - return; + return false; } break; - //} + //} default: break; - } - else switch (mobj->type) + } + + return true; +} + +static boolean P_MobjRegularThink(mobj_t *mobj) +{ + switch (mobj->type) { case MT_FALLINGROCK: // Despawn rocks here in case zmovement code can't do so (blame slopes) @@ -7226,7 +7124,7 @@ void P_MobjThinker(mobj_t *mobj) || mobj->target->state == &states[mobj->target->info->raisestate]) { P_RemoveMobj(mobj); - return; + return false; } P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z - mobj->height); break; @@ -7234,7 +7132,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->z <= mobj->floorz) { P_RemoveMobj(mobj); - return; + return false; } break; case MT_KOOPA: @@ -7245,11 +7143,11 @@ void P_MobjThinker(mobj_t *mobj) && mobj->flags & MF_MISSILE) { P_ExplodeMissile(mobj); - return; + return false; } break; case MT_BOSSFLYPOINT: - return; + return false; case MT_NIGHTSCORE: mobj->color = (UINT8)(leveltime % SKINCOLOR_WHITE); break; @@ -7261,7 +7159,7 @@ void P_MobjThinker(mobj_t *mobj) || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now { // then remove yourself as well! P_RemoveMobj(mobj); - return; + return false; } jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); @@ -7332,7 +7230,7 @@ void P_MobjThinker(mobj_t *mobj) || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now { // then remove yourself as well! P_RemoveMobj(mobj); - return; + return false; } jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); @@ -7354,7 +7252,7 @@ void P_MobjThinker(mobj_t *mobj) || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now { // then remove yourself as well! P_RemoveMobj(mobj); - return; + return false; } P_UnsetThingPosition(mobj); @@ -7428,7 +7326,7 @@ void P_MobjThinker(mobj_t *mobj) case MT_PLAYER: if (mobj->player) P_PlayerMobjThinker(mobj); - return; + return false; case MT_SKIM: // check mobj against possible water content, before movement code P_MobjCheckWater(mobj); @@ -7463,7 +7361,7 @@ void P_MobjThinker(mobj_t *mobj) P_NightsItemChase(mobj); else A_AttractChase(mobj); - return; + return false; // Flung items case MT_FLINGRING: case MT_FLINGCOIN: @@ -7501,7 +7399,7 @@ void P_MobjThinker(mobj_t *mobj) if (P_CheckDeathPitCollide(mobj)) { P_RemoveMobj(mobj); - return; + return false; } else if (P_IsObjectOnGround(mobj)) { @@ -7520,7 +7418,7 @@ void P_MobjThinker(mobj_t *mobj) || mobj->scale <= mapobjectscale>>4) { P_RemoveMobj(mobj); - return; + return false; } P_Attract(mobj, mobj->tracer, true); } @@ -7806,7 +7704,7 @@ void P_MobjThinker(mobj_t *mobj) // you can cycle through multiple states in a tic if (!mobj->tics) if (!P_SetMobjState(mobj, mobj->state->nextstate)) - return; // freed itself + return false; // freed itself } P_UnsetThingPosition(mobj); @@ -7814,7 +7712,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->y += mobj->momy; mobj->z += mobj->momz; P_SetThingPosition(mobj); - return; + return false; case MT_MINEEXPLOSIONSOUND: if (mobj->health == 100) S_StartSound(mobj, sfx_s3k4e); @@ -7824,7 +7722,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target || !mobj->target->health) { P_RemoveMobj(mobj); - return; + return false; } mobj->angle = mobj->target->angle; @@ -7866,7 +7764,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target) { P_RemoveMobj(mobj); - return; + return false; } mobj->color = mobj->target->color; mobj->colorized = mobj->target->colorized; @@ -7875,7 +7773,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_invincibilitytimer])) { P_RemoveMobj(mobj); - return; + return false; } P_SetOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); break; @@ -7886,7 +7784,7 @@ void P_MobjThinker(mobj_t *mobj) || !(mobj->target->player->cmd.buttons & BT_ACCELERATE))) // Letting go of accel functions about the same as brake-drifting { P_RemoveMobj(mobj); - return; + return false; } else { @@ -7923,7 +7821,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target || !mobj->target->health) { P_RemoveMobj(mobj); - return; + return false; } P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); break; @@ -7934,7 +7832,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield])) { P_RemoveMobj(mobj); - return; + return false; } K_MatchGenericExtraFlags(mobj, mobj->target); @@ -7944,7 +7842,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target || P_MobjWasRemoved(mobj->target)) { P_RemoveMobj(mobj); - return; + return false; } if (mobj->movefactor < 48*mobj->target->scale) @@ -7968,7 +7866,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target || !mobj->target->health || (mobj->target->player && mobj->target->player->kartstuff[k_curshield] != 1)) { P_RemoveMobj(mobj); - return; + return false; } P_SetScale(mobj, (mobj->destscale = (5*mobj->target->destscale)>>2)); @@ -8004,7 +7902,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target || !mobj->target->health) { P_RemoveMobj(mobj); - return; + return false; } if (mobj->target->player && !mobj->target->player->kartstuff[k_rocketsneakertimer]) { @@ -8018,7 +7916,7 @@ void P_MobjThinker(mobj_t *mobj) else if (P_IsObjectOnGround(mobj)) { P_RemoveMobj(mobj); - return; + return false; } } break; @@ -8030,7 +7928,7 @@ void P_MobjThinker(mobj_t *mobj) || (G_RaceGametype() || mobj->target->player->kartstuff[k_bumper])) { P_RemoveMobj(mobj); - return; + return false; } P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); @@ -8516,7 +8414,7 @@ void P_MobjThinker(mobj_t *mobj) if (!mobj->target || P_MobjWasRemoved(mobj->target)) { P_RemoveMobj(mobj); - return; + return false; } break; case MT_SMK_PIPE: @@ -8530,7 +8428,7 @@ void P_MobjThinker(mobj_t *mobj) { mobj_t *newmole = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_MOLE); P_SetTarget(&mobj->target, newmole); - return; + return false; } break; case MT_SMK_MOLE: @@ -8672,7 +8570,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->momz == 0) { P_RemoveMobj(mobj); - return; + return false; } else { @@ -8690,7 +8588,7 @@ void P_MobjThinker(mobj_t *mobj) P_MobjCheckWater(mobj); P_CheckPosition(mobj, mobj->x, mobj->y); if (P_MobjWasRemoved(mobj)) - return; + return false; mobj->floorz = tmfloorz; mobj->ceilingz = tmceilingz; @@ -8760,52 +8658,403 @@ void P_MobjThinker(mobj_t *mobj) && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) { P_KillMobj(mobj, NULL, NULL); - return; + return false; } break; } + + return true; +} + +static void P_FlagFuseThink(mobj_t *mobj) +{ + subsector_t *ss; + fixed_t x, y, z; + mobj_t* flagmo; + + if (!mobj->spawnpoint) + return; + + x = mobj->spawnpoint->x << FRACBITS; + y = mobj->spawnpoint->y << FRACBITS; + ss = R_PointInSubsector(x, y); + if (mobj->spawnpoint->options & MTF_OBJECTFLIP) + { + z = ss->sector->ceilingheight - mobjinfo[mobj->type].height; + if (mobj->spawnpoint->options >> ZSHIFT) + z -= (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; + } + else + { + z = ss->sector->floorheight; + if (mobj->spawnpoint->options >> ZSHIFT) + z += (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; + } + flagmo = P_SpawnMobj(x, y, z, mobj->type); + flagmo->spawnpoint = mobj->spawnpoint; + if (mobj->spawnpoint->options & MTF_OBJECTFLIP) + { + flagmo->eflags |= MFE_VERTICALFLIP; + flagmo->flags2 |= MF2_OBJECTFLIP; + } + + if (mobj->type == MT_REDFLAG) + { + if (!(mobj->flags2 & MF2_JUSTATTACKED)) + CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80); + + // Assumedly in splitscreen players will be on opposing teams + if (players[consoleplayer].ctfteam == 1 || splitscreen) + S_StartSound(NULL, sfx_hoop1); + else if (players[consoleplayer].ctfteam == 2) + S_StartSound(NULL, sfx_hoop3); + + redflag = flagmo; + } + else // MT_BLUEFLAG + { + if (!(mobj->flags2 & MF2_JUSTATTACKED)) + CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80); + + // Assumedly in splitscreen players will be on opposing teams + if (players[consoleplayer].ctfteam == 2 || splitscreen) + S_StartSound(NULL, sfx_hoop1); + else if (players[consoleplayer].ctfteam == 1) + S_StartSound(NULL, sfx_hoop3); + + blueflag = flagmo; + } + + P_RemoveMobj(mobj); +} + + +static void P_MonitorFuseThink(mobj_t *mobj) +{ + mobj_t *newmobj; + + if ((mobj->flags2 & MF2_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX) + { + mobjtype_t spawnchance[64]; + INT32 numchoices = 0, i = 0; + + // This define should make it a lot easier to organize and change monitor weights +#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \ + for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type + + // Type SRM WRM + SETMONITORCHANCES(MT_SNEAKERTV, 0, 10); // Super Sneakers + SETMONITORCHANCES(MT_INV, 2, 0); // Invincibility + SETMONITORCHANCES(MT_WHITETV, 3, 8); // Whirlwind Shield + SETMONITORCHANCES(MT_GREENTV, 3, 8); // Elemental Shield + SETMONITORCHANCES(MT_YELLOWTV, 2, 0); // Attraction Shield + SETMONITORCHANCES(MT_BLUETV, 3, 3); // Force Shield + SETMONITORCHANCES(MT_BLACKTV, 2, 0); // Armageddon Shield + SETMONITORCHANCES(MT_MIXUPBOX, 0, 1); // Teleporters + SETMONITORCHANCES(MT_RECYCLETV, 0, 1); // Recycler + SETMONITORCHANCES(MT_PRUP, 1, 1); // 1-Up + // ====================================== + // Total 16 32 + +#undef SETMONITORCHANCES + + i = P_RandomKey(numchoices); // Gotta love those random numbers! + newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); + + // Transfer flags2 (strongbox, objectflip, ambush) + newmobj->flags2 = mobj->flags2; + } + else + { + newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); + + // Transfer flags2 (strongbox, objectflip) + newmobj->flags2 = mobj->flags2; + } + + P_RemoveMobj(mobj); // make sure they disappear +} + +static void P_IceBlockFuseThink(mobj_t *mobj) +{ + mobj_t *cur = mobj->hnext, *next; + UINT8 i; + + for (i = 0; i < 5; i++) + { + mobj_t *debris = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_DEBRIS); + debris->angle = FixedAngle(P_RandomRange(0,360)<angle, P_RandomRange(3,18)*(FRACUNIT/4)); + debris->momz = P_RandomRange(4,8)<hnext; + P_RemoveMobj(cur); + cur = next; + } + + P_RemoveMobj(mobj); +} + +static boolean P_FuseThink(mobj_t *mobj) +{ + if (((mobj->type == MT_RANDOMITEM && mobj->threshold == 69) || mobj->type == MT_EGGMANITEM || mobj->type == MT_FALLINGROCK) && mobj->fuse <= TICRATE) + mobj->flags2 ^= MF2_DONTDRAW; + + mobj->fuse--; + + if (mobj->fuse) + return true; + + if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)) || P_MobjWasRemoved(mobj)) + ; + else switch (mobj->type) + { + // gargoyle and snowman handled in P_PushableThinker, not here + case MT_THROWNGRENADE: + case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: + P_SetMobjState(mobj, mobj->info->deathstate); + break; + case MT_BLUEFLAG: + case MT_REDFLAG: + P_FlagFuseThink(mobj); + return false; + case MT_YELLOWTV: // Ring shield box + case MT_BLUETV: // Force shield box + case MT_GREENTV: // Water shield box + case MT_BLACKTV: // Bomb shield box + case MT_WHITETV: // Jump shield box + case MT_SNEAKERTV: // Super Sneaker box + case MT_SUPERRINGBOX: // 10-Ring box + case MT_REDRINGBOX: // Red Team 10-Ring box + case MT_BLUERINGBOX: // Blue Team 10-Ring box + case MT_INV: // Invincibility box + case MT_MIXUPBOX: // Teleporter Mixup box + case MT_RECYCLETV: // Recycler box + case MT_SCORETVSMALL: + case MT_SCORETVLARGE: + case MT_PRUP: // 1up! + case MT_EGGMANBOX: // Eggman box + case MT_GRAVITYBOX: // Gravity box + case MT_QUESTIONBOX: + P_MonitorFuseThink(mobj); + return false; + case MT_METALSONIC_BATTLE: + break; // don't remove + case MT_SPIKE: + P_SetMobjState(mobj, mobj->state->nextstate); + mobj->fuse = mobj->info->speed; + if (mobj->spawnpoint) + mobj->fuse += mobj->spawnpoint->angle; + break; + case MT_NIGHTSCORE: + P_RemoveMobj(mobj); + return false; + case MT_PLAYER: + break; // don't remove + case MT_SMK_ICEBLOCK: + P_IceBlockFuseThink(mobj); + return false; + default: + P_SetMobjState(mobj, mobj->info->xdeathstate); // will remove the mobj if S_NULL. + break; + } + + return !P_MobjWasRemoved(mobj); +} + +static boolean P_MobjPushableThink(mobj_t *mobj) +{ + // would be cool if we could use P_MobjWasRemoved Zzz... + if (!mobj) + return false; + + P_MobjCheckWater(mobj); + P_PushableThinker(mobj); + + // Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.) + if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL + && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) + { + P_KillMobj(mobj, NULL, NULL); + return false; + } + + return true; +} + +static void P_FiringThink(mobj_t *mobj) +{ + if (mobj->state->action.acp1 == (actionf_p1)A_Boss1Laser) + { + var1 = mobj->state->var1; + var2 = mobj->state->var2; + mobj->state->action.acp1(mobj); + } + else if (leveltime & 1) // Fire mode + { + mobj_t *missile; + + if (mobj->target->player && mobj->target->player->nightstime) + { + fixed_t oldval = mobjinfo[mobj->extravalue1].speed; + + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x+mobj->target->momx, mobj->target->y+mobj->target->momy); + mobjinfo[mobj->extravalue1].speed = FixedMul(60*FRACUNIT, mobj->scale); + missile = P_SpawnMissile(mobj, mobj->target, mobj->extravalue1); + mobjinfo[mobj->extravalue1].speed = oldval; + } + else + { + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + missile = P_SpawnMissile(mobj, mobj->target, mobj->extravalue1); + } + + if (missile) + { + if (mobj->flags2 & MF2_SUPERFIRE) + missile->flags2 |= MF2_SUPERFIRE; + + if (mobj->info->attacksound) + S_StartSound(missile, mobj->info->attacksound); + } + } + else + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); +} + +// +// P_MobjThinker +// +void P_MobjThinker(mobj_t *mobj) +{ + I_Assert(mobj != NULL); + I_Assert(!P_MobjWasRemoved(mobj)); + + if (mobj->flags & MF_NOTHINK) + return; + + // Remove dead target/tracer. + if (mobj->target && P_MobjWasRemoved(mobj->target)) + P_SetTarget(&mobj->target, NULL); + if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) + P_SetTarget(&mobj->tracer, NULL); + // hnext/hprev changes suggested by toaster + if (mobj->hnext && P_MobjWasRemoved(mobj->hnext)) + P_SetTarget(&mobj->hnext, NULL); + if (mobj->hprev && P_MobjWasRemoved(mobj->hprev)) + P_SetTarget(&mobj->hprev, NULL); + + mobj->flags2 &= ~MF2_PUSHED; + mobj->eflags &= ~(MFE_SPRUNG|MFE_JUSTBOUNCEDWALL); + + tmfloorthing = tmhitthing = NULL; + + // 970 allows ANY mobj to trigger a linedef exec + if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8) + { + sector_t *sec2; + + sec2 = P_ThingOnSpecial3DFloor(mobj); + if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1) + P_LinedefExecute(sec2->tag, mobj, sec2); + } + + // Slowly scale up/down to reach your destscale. + if (mobj->scale != mobj->destscale) + { + fixed_t oldheight = mobj->height; + UINT8 correctionType = 0; // Don't correct Z position, just gain height + + if (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz + && mobj->type != MT_EGGMOBILE_FIRE) + correctionType = 1; // Correct Z position by centering + else if (mobj->eflags & MFE_VERTICALFLIP) + correctionType = 2; // Correct Z position by moving down + + if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed) + P_SetScale(mobj, mobj->destscale); + else if (mobj->scale < mobj->destscale) + P_SetScale(mobj, mobj->scale + mobj->scalespeed); + else if (mobj->scale > mobj->destscale) + P_SetScale(mobj, mobj->scale - mobj->scalespeed); + + if (correctionType == 1) + mobj->z -= (mobj->height - oldheight)/2; + else if (correctionType == 2) + mobj->z -= mobj->height - oldheight; + + if (mobj->scale == mobj->destscale) + /// \todo Lua hook for "reached destscale"? + switch(mobj->type) + { + case MT_EGGMOBILE_FIRE: + mobj->destscale = FRACUNIT; + mobj->scalespeed = FRACUNIT>>4; + break; + default: + break; + } + } + + if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY! + && (signed)(mobj->frame >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2) + // fade out when nearing the end of fuse... + mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT); + + // Special thinker for scenery objects + if (mobj->flags & MF_SCENERY) + { + P_MobjSceneryThink(mobj); + return; + } + + // Check for a Lua thinker first + if (!mobj->player) + { + if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker)) || P_MobjWasRemoved(mobj)) + return; + } + else if (!mobj->player->spectator) + { + // You cannot short-circuit the player thinker like you can other thinkers. + LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker)); + if (P_MobjWasRemoved(mobj)) + return; + } + + // if it's pushable, or if it would be pushable other than temporary disablement, use the + // separate thinker + if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse)) + { + if (!P_MobjPushableThink(mobj)) + return; + } + else if (mobj->flags & MF_BOSS) + { + if (!P_MobjBossThink(mobj)) + return; + } + else if (mobj->health <= 0) // Dead things think differently than the living. + { + if (!P_MobjDeadThink(mobj)) + return; + } + else + { + if (!P_MobjRegularThink(mobj)) + return; + } + if (P_MobjWasRemoved(mobj)) return; if (mobj->flags2 & MF2_FIRING && mobj->target && mobj->health > 0) - { - if (mobj->state->action.acp1 == (actionf_p1)A_Boss1Laser) - { - var1 = mobj->state->var1; - var2 = mobj->state->var2; - mobj->state->action.acp1(mobj); - } - else if (leveltime & 1) // Fire mode - { - mobj_t *missile; - - if (mobj->target->player && mobj->target->player->nightstime) - { - fixed_t oldval = mobjinfo[mobj->extravalue1].speed; - - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x+mobj->target->momx, mobj->target->y+mobj->target->momy); - mobjinfo[mobj->extravalue1].speed = FixedMul(60*FRACUNIT, mobj->scale); - missile = P_SpawnMissile(mobj, mobj->target, mobj->extravalue1); - mobjinfo[mobj->extravalue1].speed = oldval; - } - else - { - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - missile = P_SpawnMissile(mobj, mobj->target, mobj->extravalue1); - } - - if (missile) - { - if (mobj->flags2 & MF2_SUPERFIRE) - missile->flags2 |= MF2_SUPERFIRE; - - if (mobj->info->attacksound) - S_StartSound(missile, mobj->info->attacksound); - } - } - else - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - } + P_FiringThink(mobj); if (mobj->flags & MF_AMBIENT) { @@ -8815,209 +9064,8 @@ void P_MobjThinker(mobj_t *mobj) } // Check fuse - if (mobj->fuse) - { - mobj->fuse--; - if (!mobj->fuse) - { - subsector_t *ss; - fixed_t x, y, z; - mobj_t *flagmo, *newmobj; - - if (!LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)) && !P_MobjWasRemoved(mobj)) - { - switch (mobj->type) - { - // gargoyle and snowman handled in P_PushableThinker, not here - case MT_THROWNGRENADE: - case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: - P_SetMobjState(mobj, mobj->info->deathstate); - break; - case MT_BLUEFLAG: - case MT_REDFLAG: - if (mobj->spawnpoint) - { - x = mobj->spawnpoint->x << FRACBITS; - y = mobj->spawnpoint->y << FRACBITS; - ss = R_PointInSubsector(x, y); - if (mobj->spawnpoint->options & MTF_OBJECTFLIP) - { - z = ss->sector->ceilingheight - mobjinfo[mobj->type].height; - if (mobj->spawnpoint->options >> ZSHIFT) - z -= (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; - } - else - { - z = ss->sector->floorheight; - if (mobj->spawnpoint->options >> ZSHIFT) - z += (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; - } - flagmo = P_SpawnMobj(x, y, z, mobj->type); - flagmo->spawnpoint = mobj->spawnpoint; - if (mobj->spawnpoint->options & MTF_OBJECTFLIP) - { - flagmo->eflags |= MFE_VERTICALFLIP; - flagmo->flags2 |= MF2_OBJECTFLIP; - } - - if (mobj->type == MT_REDFLAG) - { - if (!(mobj->flags2 & MF2_JUSTATTACKED)) - CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80); - - // Assumedly in splitscreen players will be on opposing teams - if (players[consoleplayer].ctfteam == 1 || splitscreen) - S_StartSound(NULL, sfx_hoop1); - else if (players[consoleplayer].ctfteam == 2) - S_StartSound(NULL, sfx_hoop3); - - redflag = flagmo; - } - else // MT_BLUEFLAG - { - if (!(mobj->flags2 & MF2_JUSTATTACKED)) - CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80); - - // Assumedly in splitscreen players will be on opposing teams - if (players[consoleplayer].ctfteam == 2 || splitscreen) - S_StartSound(NULL, sfx_hoop1); - else if (players[consoleplayer].ctfteam == 1) - S_StartSound(NULL, sfx_hoop3); - - blueflag = flagmo; - } - } - P_RemoveMobj(mobj); - return; - case MT_YELLOWTV: // Ring shield box - case MT_BLUETV: // Force shield box - case MT_GREENTV: // Water shield box - case MT_BLACKTV: // Bomb shield box - case MT_WHITETV: // Jump shield box - case MT_SNEAKERTV: // Super Sneaker box - case MT_SUPERRINGBOX: // 10-Ring box - case MT_REDRINGBOX: // Red Team 10-Ring box - case MT_BLUERINGBOX: // Blue Team 10-Ring box - case MT_INV: // Invincibility box - case MT_MIXUPBOX: // Teleporter Mixup box - case MT_RECYCLETV: // Recycler box - case MT_SCORETVSMALL: - case MT_SCORETVLARGE: - case MT_PRUP: // 1up! - case MT_EGGMANBOX: // Eggman box - case MT_GRAVITYBOX: // Gravity box - case MT_QUESTIONBOX: - if ((mobj->flags2 & MF2_AMBUSH || mobj->flags2 & MF2_STRONGBOX) && mobj->type != MT_QUESTIONBOX) - { - mobjtype_t spawnchance[64]; - INT32 numchoices = 0, i = 0; - - // This define should make it a lot easier to organize and change monitor weights -#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \ - for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type - - // Type SRM WRM - SETMONITORCHANCES(MT_SNEAKERTV, 0, 10); // Super Sneakers - SETMONITORCHANCES(MT_INV, 2, 0); // Invincibility - SETMONITORCHANCES(MT_WHITETV, 3, 8); // Whirlwind Shield - SETMONITORCHANCES(MT_GREENTV, 3, 8); // Elemental Shield - SETMONITORCHANCES(MT_YELLOWTV, 2, 0); // Attraction Shield - SETMONITORCHANCES(MT_BLUETV, 3, 3); // Force Shield - SETMONITORCHANCES(MT_BLACKTV, 2, 0); // Armageddon Shield - SETMONITORCHANCES(MT_MIXUPBOX, 0, 1); // Teleporters - SETMONITORCHANCES(MT_RECYCLETV, 0, 1); // Recycler - SETMONITORCHANCES(MT_PRUP, 1, 1); // 1-Up - // ====================================== - // Total 16 32 - -#undef SETMONITORCHANCES - - i = P_RandomKey(numchoices); // Gotta love those random numbers! - newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); - - // Transfer flags2 (strongbox, objectflip, ambush) - newmobj->flags2 = mobj->flags2; - } - else - { - newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); - - // Transfer flags2 (strongbox, objectflip) - newmobj->flags2 = mobj->flags2; - } - P_RemoveMobj(mobj); // make sure they disappear - return; - case MT_RANDOMITEM: - if (G_BattleGametype()) - { - if (mobj->threshold != 69) - break; - } - else - { - // Respawn from mapthing if you have one! - if (mobj->spawnpoint) - { - P_SpawnMapThing(mobj->spawnpoint); - newmobj = mobj->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing - } - else - newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); - - // Transfer flags2 (strongbox, objectflip) - newmobj->flags2 = mobj->flags2 & ~MF2_DONTDRAW; - } - P_RemoveMobj(mobj); // make sure they disappear - return; - case MT_METALSONIC_BATTLE: - break; // don't remove - case MT_SPIKE: - P_SetMobjState(mobj, mobj->state->nextstate); - mobj->fuse = mobj->info->speed; - if (mobj->spawnpoint) - mobj->fuse += mobj->spawnpoint->angle; - break; - case MT_NIGHTSCORE: - P_RemoveMobj(mobj); - return; - case MT_PLAYER: - break; // don't remove - case MT_SMK_ICEBLOCK: - { - mobj_t *cur = mobj->hnext, *next; - UINT8 i; - - for (i = 0; i < 5; i++) - { - mobj_t *debris = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_DEBRIS); - debris->angle = FixedAngle(P_RandomRange(0,360)<angle, P_RandomRange(3,18)*(FRACUNIT/4)); - debris->momz = P_RandomRange(4,8)<hnext; - P_RemoveMobj(cur); - cur = next; - } - - P_RemoveMobj(mobj); - return; - } - default: - P_SetMobjState(mobj, mobj->info->xdeathstate); // will remove the mobj if S_NULL. - break; - } - } - if (P_MobjWasRemoved(mobj)) - return; - } - else if (((mobj->type == MT_RANDOMITEM && mobj->threshold == 69) || mobj->type == MT_EGGMANITEM || mobj->type == MT_FALLINGROCK) && mobj->fuse <= TICRATE) - mobj->flags2 ^= MF2_DONTDRAW; - } + if (mobj->fuse && !P_FuseThink(mobj)) + return; I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); -- 2.54.0 From c546b6225ce6051aa0e9b55970cafb564173333c Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 12 Apr 2025 18:10:07 +0200 Subject: [PATCH 2/9] move this since it does check for fuse --- src/p_mobj.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 095804cd9..002b21df4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8802,13 +8802,15 @@ static void P_IceBlockFuseThink(mobj_t *mobj) static boolean P_FuseThink(mobj_t *mobj) { - if (((mobj->type == MT_RANDOMITEM && mobj->threshold == 69) || mobj->type == MT_EGGMANITEM || mobj->type == MT_FALLINGROCK) && mobj->fuse <= TICRATE) - mobj->flags2 ^= MF2_DONTDRAW; - mobj->fuse--; if (mobj->fuse) + { + if (((mobj->type == MT_RANDOMITEM && mobj->threshold == 69) || mobj->type == MT_EGGMANITEM || mobj->type == MT_FALLINGROCK) && mobj->fuse <= TICRATE) + mobj->flags2 ^= MF2_DONTDRAW; + return true; + } if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)) || P_MobjWasRemoved(mobj)) ; -- 2.54.0 From a0f8816de7cce6cef689dc1582d982b848ee6a07 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 13 Apr 2025 09:02:58 +0200 Subject: [PATCH 3/9] readd itembox fuse think that was lost somehow lmao --- src/p_mobj.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 002b21df4..8fc0c040d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8775,6 +8775,33 @@ static void P_MonitorFuseThink(mobj_t *mobj) P_RemoveMobj(mobj); // make sure they disappear } +static boolean P_RandomItemFuseThink(mobj_t *mobj) +{ + mobj_t *newmobj; + + if (G_BattleGametype()) + { + if (mobj->threshold != 69) + return false; + } + else + { + // Respawn from mapthing if you have one! + if (mobj->spawnpoint) + { + P_SpawnMapThing(mobj->spawnpoint); + newmobj = mobj->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing + } + else + newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); + + // Transfer flags2 (strongbox, objectflip) + newmobj->flags2 = mobj->flags2 & ~MF2_DONTDRAW; + } + + return true; +} + static void P_IceBlockFuseThink(mobj_t *mobj) { mobj_t *cur = mobj->hnext, *next; @@ -8845,6 +8872,11 @@ static boolean P_FuseThink(mobj_t *mobj) case MT_QUESTIONBOX: P_MonitorFuseThink(mobj); return false; + case MT_RANDOMITEM: + if (!P_RandomItemFuseThink(mobj)) + break; + P_RemoveMobj(mobj); // make sure they disappear + return false; case MT_METALSONIC_BATTLE: break; // don't remove case MT_SPIKE: -- 2.54.0 From 311258dda01e6d91967f7d044ad4584992ed06a9 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 23 May 2025 16:24:50 +0200 Subject: [PATCH 4/9] more unnesting for mobj think stuff --- src/p_mobj.c | 145 ++++++++++++++++++++++++++------------------------- 1 file changed, 75 insertions(+), 70 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 8fc0c040d..5366a6320 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6056,6 +6056,42 @@ angle_t P_MobjPitchAndRoll(mobj_t *mobj) return return_angle; } +static void P_MobjScaleThink(mobj_t *mobj) +{ + fixed_t oldheight = mobj->height; + UINT8 correctionType = 0; // Don't correct Z position, just gain height + + if (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz + && mobj->type != MT_EGGMOBILE_FIRE) + correctionType = 1; // Correct Z position by centering + else if (mobj->eflags & MFE_VERTICALFLIP) + correctionType = 2; // Correct Z position by moving down + + if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed) + P_SetScale(mobj, mobj->destscale); + else if (mobj->scale < mobj->destscale) + P_SetScale(mobj, mobj->scale + mobj->scalespeed); + else if (mobj->scale > mobj->destscale) + P_SetScale(mobj, mobj->scale - mobj->scalespeed); + + if (correctionType == 1) + mobj->z -= (mobj->height - oldheight)/2; + else if (correctionType == 2) + mobj->z -= mobj->height - oldheight; + + if (mobj->scale == mobj->destscale) + /// \todo Lua hook for "reached destscale"? + switch(mobj->type) + { + case MT_EGGMOBILE_FIRE: + mobj->destscale = FRACUNIT; + mobj->scalespeed = FRACUNIT>>4; + break; + default: + break; + } +} + // Special thinker for scenery objects // this does not need to return anything static void P_MobjSceneryThink(mobj_t *mobj) @@ -8998,42 +9034,8 @@ void P_MobjThinker(mobj_t *mobj) P_LinedefExecute(sec2->tag, mobj, sec2); } - // Slowly scale up/down to reach your destscale. if (mobj->scale != mobj->destscale) - { - fixed_t oldheight = mobj->height; - UINT8 correctionType = 0; // Don't correct Z position, just gain height - - if (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz - && mobj->type != MT_EGGMOBILE_FIRE) - correctionType = 1; // Correct Z position by centering - else if (mobj->eflags & MFE_VERTICALFLIP) - correctionType = 2; // Correct Z position by moving down - - if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed) - P_SetScale(mobj, mobj->destscale); - else if (mobj->scale < mobj->destscale) - P_SetScale(mobj, mobj->scale + mobj->scalespeed); - else if (mobj->scale > mobj->destscale) - P_SetScale(mobj, mobj->scale - mobj->scalespeed); - - if (correctionType == 1) - mobj->z -= (mobj->height - oldheight)/2; - else if (correctionType == 2) - mobj->z -= mobj->height - oldheight; - - if (mobj->scale == mobj->destscale) - /// \todo Lua hook for "reached destscale"? - switch(mobj->type) - { - case MT_EGGMOBILE_FIRE: - mobj->destscale = FRACUNIT; - mobj->scalespeed = FRACUNIT>>4; - break; - default: - break; - } - } + P_MobjScaleThink(mobj); // Slowly scale up/down to reach your destscale. if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY! && (signed)(mobj->frame >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2) @@ -9092,7 +9094,9 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags & MF_AMBIENT) { - if (!(leveltime % mobj->health) && mobj->info->seesound) + if (leveltime % mobj->health) + return; + if (mobj->info->seesound) S_StartSound(mobj, mobj->info->seesound); return; } @@ -9291,6 +9295,39 @@ void P_PushableThinker(mobj_t *mobj) } } +static void P_RandomAudienceThink(mobj_t *mobj) +{ + if (!mobj->colorized) // a fan of someone? + return; + + if (mobj->threshold >= 0) // not already happy or sad? + { + if (!playeringame[mobj->threshold] || players[mobj->threshold].spectator) // focused on a valid player? + return; + + if (!(players[mobj->threshold].exiting) && !(players[mobj->threshold].pflags & PF_TIMEOVER)) // not finished yet? + return; + + if (K_IsPlayerLosing(&players[mobj->threshold])) + mobj->threshold = -2; + else + { + mobj->threshold = -1; + S_StartSound(mobj, sfx_chaooo); + } + } + + if (mobj->threshold == -1) + mobj->angle += ANGLE_22h; + + if (((statenum_t)(mobj->state-states) != S_AUDIENCE_CHAO_CHEER2) || (mobj->tics != states[S_AUDIENCE_CHAO_CHEER2].tics)) // not at the start of your cheer jump? + return; + + mobj->momz = 0; + + P_SetMobjState(mobj, ((mobj->threshold == -1) ? S_AUDIENCE_CHAO_WIN2 : S_AUDIENCE_CHAO_LOSE)); +} + // Quick, optimized function for scenery void P_SceneryThinker(mobj_t *mobj) { @@ -9344,40 +9381,8 @@ void P_SceneryThinker(mobj_t *mobj) P_CycleMobjState(mobj); - if (mobj->type != MT_RANDOMAUDIENCE) - return; - - { - if (!mobj->colorized) // a fan of someone? - return; - - if (mobj->threshold >= 0) // not already happy or sad? - { - if (!playeringame[mobj->threshold] || players[mobj->threshold].spectator) // focused on a valid player? - return; - - if (!(players[mobj->threshold].exiting) && !(players[mobj->threshold].pflags & PF_TIMEOVER)) // not finished yet? - return; - - if (K_IsPlayerLosing(&players[mobj->threshold])) - mobj->threshold = -2; - else - { - mobj->threshold = -1; - S_StartSound(mobj, sfx_chaooo); - } - } - - if (mobj->threshold == -1) - mobj->angle += ANGLE_22h; - - if (((statenum_t)(mobj->state-states) != S_AUDIENCE_CHAO_CHEER2) || (mobj->tics != states[S_AUDIENCE_CHAO_CHEER2].tics)) // not at the start of your cheer jump? - return; - - mobj->momz = 0; - - P_SetMobjState(mobj, ((mobj->threshold == -1) ? S_AUDIENCE_CHAO_WIN2 : S_AUDIENCE_CHAO_LOSE)); - } + if (mobj->type == MT_RANDOMAUDIENCE) + P_RandomAudienceThink(mobj); } // -- 2.54.0 From fa3dcdb24f84f01d8deb3726ca33d58e446b33bd Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 23 May 2025 16:31:17 +0200 Subject: [PATCH 5/9] massive cleanup p_mobj --- src/p_mobj.c | 644 +++++++++++++++++++++++++-------------------------- 1 file changed, 313 insertions(+), 331 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5366a6320..38a772b1e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -328,10 +328,11 @@ boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state) state_t *st; if (state == S_NULL) - { // Remove mobj - P_RemoveMobj(mobj); + { + P_RemoveMobj(mobj); // Remove mobj return false; } + st = &states[state]; mobj->state = st; mobj->tics = st->tics; @@ -347,10 +348,11 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state) state_t *st; if (state == S_NULL) - { // Remove mobj - P_FreePrecipMobj(mobj); + { + P_FreePrecipMobj(mobj); // Remove mobj return false; } + st = &states[state]; mobj->state = st; mobj->tics = st->tics; @@ -368,19 +370,7 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state) // boolean P_WeaponOrPanel(mobjtype_t type) { - if (type == MT_BOUNCERING - || type == MT_AUTOMATICRING - || type == MT_INFINITYRING - || type == MT_RAILRING - || type == MT_EXPLOSIONRING - || type == MT_SCATTERRING - || type == MT_GRENADERING - || type == MT_BOUNCEPICKUP - || type == MT_RAILPICKUP - || type == MT_AUTOPICKUP - || type == MT_EXPLODEPICKUP - || type == MT_SCATTERPICKUP - || type == MT_GRENADEPICKUP) + if (type >= MT_BOUNCERING && type <= MT_GRENADEPICKUP) return true; return false; @@ -406,6 +396,7 @@ void P_ExplodeMissile(mobj_t *mo) P_RadiusAttack(mo, mo, 96*FRACUNIT); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); + if (explodemo) { P_SetScale(explodemo, mo->scale); @@ -414,7 +405,9 @@ void P_ExplodeMissile(mobj_t *mo) explodemo->momy += (P_RandomByte() % 32) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_pop); } + explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); + if (explodemo) { P_SetScale(explodemo, mo->scale); @@ -423,7 +416,9 @@ void P_ExplodeMissile(mobj_t *mo) explodemo->momy -= (P_RandomByte() % 64) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_dmpain); } + explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); + if (explodemo) { P_SetScale(explodemo, mo->scale); @@ -432,7 +427,9 @@ void P_ExplodeMissile(mobj_t *mo) explodemo->momy += (P_RandomByte() % 128) * FixedMul(FRACUNIT/8, explodemo->scale); S_StartSound(explodemo, sfx_pop); } + explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); + if (explodemo) { P_SetScale(explodemo, mo->scale); @@ -473,10 +470,7 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); - if (mobj->z > topheight) - return false; - - if (mobj->z + mobj->height < bottomheight) + if (mobj->z > topheight || (mobj->z + mobj->height < bottomheight)) return false; return true; @@ -499,18 +493,8 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, v2.x = line->v2->x; v2.y = line->v2->y; - /*CONS_Printf("BEFORE: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v2.x, v2.y)) - );*/ - - if (abs(v1.x-x) > radius) { + if (abs(v1.x-x) > radius) + { // v1's x is out of range, so rein it in fixed_t diff = abs(v1.x-x) - radius; @@ -523,7 +507,8 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, } } - if (abs(v1.y-y) > radius) { + if (abs(v1.y-y) > radius) + { // v1's y is out of range, so rein it in fixed_t diff = abs(v1.y-y) - radius; @@ -536,7 +521,8 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, } } - if (abs(v2.x-x) > radius) { + if (abs(v2.x-x) > radius) + { // v1's x is out of range, so rein it in fixed_t diff = abs(v2.x-x) - radius; @@ -549,7 +535,8 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, } } - if (abs(v2.y-y) > radius) { + if (abs(v2.y-y) > radius) + { // v2's y is out of range, so rein it in fixed_t diff = abs(v2.y-y) - radius; @@ -562,17 +549,6 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, } } - /*CONS_Printf("AFTER: v1 = %f %f %f\n", - FIXED_TO_FLOAT(v1.x), - FIXED_TO_FLOAT(v1.y), - FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v1.x, v1.y)) - ); - CONS_Printf(" v2 = %f %f %f\n", - FIXED_TO_FLOAT(v2.x), - FIXED_TO_FLOAT(v2.y), - FIXED_TO_FLOAT(P_GetSlopeZAt(slope, v2.x, v2.y)) - );*/ - // Return the higher of the two points if (actuallylowest) return min( @@ -634,6 +610,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t bbox[BOXRIGHT] = x+mobj->radius; bbox[BOXTOP] = y+mobj->radius; bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { ld = boundsec->lines[i]; @@ -713,6 +690,7 @@ fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed bbox[BOXRIGHT] = x+mobj->radius; bbox[BOXTOP] = y+mobj->radius; bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { ld = boundsec->lines[i]; @@ -793,6 +771,7 @@ fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fix bbox[BOXRIGHT] = x+mobj->radius; bbox[BOXTOP] = y+mobj->radius; bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { ld = boundsec->lines[i]; @@ -872,6 +851,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f bbox[BOXRIGHT] = x+mobj->radius; bbox[BOXTOP] = y+mobj->radius; bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { ld = boundsec->lines[i]; @@ -1175,6 +1155,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) I_Assert(!P_MobjWasRemoved(mo)); player = mo->player; + if (player) // valid only if player avatar { // spinning friction @@ -1249,18 +1230,19 @@ static void P_PushableCheckBustables(mobj_t *mo) for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) continue; - - if (!(rover->flags & FF_BUSTUP)) continue; + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BUSTUP)) + continue; // Needs ML_EFFECT4 flag for pushables to break it - if (!(rover->master->flags & ML_EFFECT4)) continue; + if (!(rover->master->flags & ML_EFFECT4)) + continue; if (rover->master->frontsector->crumblestate) continue; topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); + // Height checks if (rover->flags & FF_SHATTERBOTTOM) { @@ -1304,6 +1286,7 @@ static void P_PushableCheckBustables(mobj_t *mo) goto bustupdone; } } + bustupdone: P_UnsetThingPosition(mo); mo->x = oldx; @@ -1422,10 +1405,11 @@ void P_XYMovement(mobj_t *mo) // blocked move moved = false; - if (player) { - if (player->bot) - B_MoveBlocked(player); + if (player && player->bot) + { + B_MoveBlocked(player); } + //{ SRB2kart - Jawz if (mo->type == MT_JAWZ || mo->type == MT_JAWZ_DUD) { @@ -1520,8 +1504,8 @@ void P_XYMovement(mobj_t *mo) return; } } - else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE)) - { // try to slide along it + else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE)) // try to slide along it + { P_SlideMove(mo, false); xmove = ymove = 0; } @@ -1579,9 +1563,10 @@ void P_XYMovement(mobj_t *mo) if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;; return; - if (moved && oldslope) { // Check to see if we ran off - - if (oldslope != mo->standingslope) { // First, compare different slopes + if (moved && oldslope) // Check to see if we ran off + { + if (oldslope != mo->standingslope) // First, compare different slopes + { angle_t oldangle, newangle; angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); @@ -1593,37 +1578,28 @@ void P_XYMovement(mobj_t *mo) newangle = 0; // Now compare the Zs of the different quantizations - if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later + if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) // Allow for a bit of sticking - this value can be adjusted later + { mo->standingslope = oldslope; P_SlopeLaunch(mo); - - //CONS_Printf("launched off of slope - "); } - - /*CONS_Printf("old angle %f - new angle %f = %f\n", - FIXED_TO_FLOAT(AngleFixed(oldangle)), - FIXED_TO_FLOAT(AngleFixed(newangle)), - FIXED_TO_FLOAT(AngleFixed(oldangle-newangle)) - );*/ - // Sryder 2018-11-26: Don't launch here if it's a slope without physics, we stick to those like glue anyway - } else if (predictedz-mo->z > abs(slopemom.z/2) - && !(mo->standingslope->flags & SL_NOPHYSICS)) { // Now check if we were supposed to stick to this slope - //CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2)); + } + else if (predictedz-mo->z > abs(slopemom.z/2) // Sryder 2018-11-26: Don't launch here if it's a slope without physics, we stick to those like glue anyway + && !(mo->standingslope->flags & SL_NOPHYSICS)) // Now check if we were supposed to stick to this slope + { P_SlopeLaunch(mo); } - } else if (moved && mo->standingslope && predictedz) { + } + else if (moved && mo->standingslope && predictedz) + { angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); - /*CONS_Printf("flat to angle %f - predicted z of %f\n", - FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)), - FIXED_TO_FLOAT(predictedz) - );*/ - if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) { + if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) + { mo->momz = P_MobjFlip(mo)*FRACUNIT/2; mo->z = predictedz + P_MobjFlip(mo); mo->standingslope = NULL; - //CONS_Printf("Launched off of flat surface running into downward slope\n"); } } @@ -1637,6 +1613,7 @@ void P_XYMovement(mobj_t *mo) P_UnsetThingPosition(mo); player->angle_pos = player->old_angle_pos; player->speed = FixedMul(player->speed, 4*FRACUNIT/5); + if (player->flyangle >= 0 && player->flyangle < 90) player->flyangle = 135; else if (player->flyangle >= 90 && player->flyangle < 180) @@ -1645,6 +1622,7 @@ void P_XYMovement(mobj_t *mo) player->flyangle = 315; else player->flyangle = 225; + player->flyangle %= 360; if (player->pflags & PF_TRANSFERTOCLOSEST) @@ -3013,6 +2991,7 @@ void P_MobjCheckWater(mobj_t *mobj) { // Spawn a splash mobj_t *splish; + if (mobj->eflags & MFE_VERTICALFLIP) { splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[MT_SPLISH].height, mobj->scale), MT_SPLISH); @@ -3021,6 +3000,7 @@ void P_MobjCheckWater(mobj_t *mobj) } else splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, MT_SPLISH); + splish->destscale = mobj->scale; P_SetScale(splish, mobj->scale); } @@ -3211,6 +3191,7 @@ void P_DestroyRobots(void) continue; // not a mobj thinker mo = (mobj_t *)think; + if (mo->health <= 0 || !(mo->flags & MF_ENEMY || mo->flags & MF_BOSS)) continue; // not a valid enemy @@ -3945,6 +3926,7 @@ static void P_Boss3Thinker(mobj_t *mobj) P_SetMobjState(mobj, mobj->info->spawnstate); mobj->reactiontime--; + if (!mobj->reactiontime) { ffloor_t *rover; @@ -3955,10 +3937,7 @@ static void P_Boss3Thinker(mobj_t *mobj) if (!playeringame[i] || players[i].spectator) continue; - if (!players[i].mo) - continue; - - if (players[i].mo->health <= 0) + if (!players[i].mo || (players[i].mo->health <= 0)) continue; if (players[i].mo->eflags & MFE_UNDERWATER) @@ -3973,10 +3952,7 @@ static void P_Boss3Thinker(mobj_t *mobj) for (rover = sectors[i].ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS)) - continue; - - if (!(rover->flags & FF_SWIMMABLE)) + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE)) continue; P_SpawnLightningFlash(rover->master->frontsector); @@ -4004,15 +3980,16 @@ static void P_Boss3Thinker(mobj_t *mobj) continue; if (players[i].mo->eflags & MFE_UNDERWATER) - { // Stay put - mobj->reactiontime = 2*TICRATE; + { + mobj->reactiontime = 2*TICRATE; // Stay put return; } } } + // Spawn pinch dummies from the center when we're leaving it. if (!mobj->reactiontime && mobj->health <= mobj->info->damage) - { // Spawn pinch dummies from the center when we're leaving it. + { thinker_t *th; mobj_t *mo2; mobj_t *dummy; @@ -4029,11 +4006,13 @@ static void P_Boss3Thinker(mobj_t *mobj) continue; mo2 = (mobj_t *)th; + if (mo2->type == (mobjtype_t)mobj->info->mass && mo2->tracer == mobj) { P_RemoveMobj(mo2); i++; } + if (i == 2) // we've already removed 2 of these, let's stop now break; } @@ -4121,16 +4100,10 @@ static void P_Boss3Thinker(mobj_t *mobj) mo2 = (mobj_t *)th; - if (!mo2) + if (!mo2 || mo2->type != MT_BOSS3WAYPOINT) continue; - if (mo2->type != MT_BOSS3WAYPOINT) - continue; - - if (!mo2->spawnpoint) - continue; - - if (mo2->spawnpoint->angle != mobj->threshold) + if (!mo2->spawnpoint || mo2->spawnpoint->angle != mobj->threshold) continue; P_SetTarget(&mobj->target, mo2); @@ -4148,7 +4121,7 @@ static void P_Boss3Thinker(mobj_t *mobj) if (dist < 1) dist = 1; - if ((mobj->movedir) || (mobj->health <= mobj->info->damage)) + if (mobj->movedir || (mobj->health <= mobj->info->damage)) speed = mobj->info->speed * 2; else speed = mobj->info->speed; @@ -4737,10 +4710,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (!playeringame[i] || players[i].spectator) continue; - if (!players[i].mo) - continue; - - if (players[i].mo->health <= 0) + if (!players[i].mo || (players[i].mo->health <= 0)) continue; if (players[i].powers[pw_ingoop]) @@ -4811,9 +4781,7 @@ static void P_Boss7Thinker(mobj_t *mobj) mo2 = (mobj_t *)th; - if (mo2->type != MT_BOSS3WAYPOINT) - continue; - if (!mo2->spawnpoint) + if (mo2->type != MT_BOSS3WAYPOINT || !mo2->spawnpoint) continue; if ((mo2->spawnpoint->options & 7) == waypointNum) @@ -4882,19 +4850,14 @@ static void P_Boss7Thinker(mobj_t *mobj) if (!playeringame[i] || players[i].spectator) continue; - if (!players[i].mo) - continue; - - if (players[i].mo->health <= 0) + if (!players[i].mo || (players[i].mo->health <= 0)) continue; if (P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > mobj->radius*4) continue; - if (players[i].mo->z > mobj->z + 128*FRACUNIT) - continue; - - if (players[i].mo->z < mobj->z - 64*FRACUNIT) + if ((players[i].mo->z > mobj->z + 128*FRACUNIT) + || (players[i].mo->z < mobj->z - 64*FRACUNIT)) continue; P_DamageMobj(players[i].mo, mobj, mobj, 1); @@ -4939,15 +4902,17 @@ static void P_Boss9Thinker(mobj_t *mobj) continue; mo2 = (mobj_t *)th; - if (mo2->type == MT_BOSS9GATHERPOINT) - { - if (last) - P_SetTarget(&last->hnext, mo2); - else - P_SetTarget(&mobj->hnext, mo2); - P_SetTarget(&mo2->hprev, last); - last = mo2; - } + + if (mo2->type != MT_BOSS9GATHERPOINT) + continue; + + if (last) + P_SetTarget(&last->hnext, mo2); + else + P_SetTarget(&mobj->hnext, mo2); + + P_SetTarget(&mo2->hprev, last); + last = mo2; } } @@ -4959,6 +4924,7 @@ static void P_Boss9Thinker(mobj_t *mobj) P_BossTargetPlayer(mobj, false); if (mobj->target && (!P_IsObjectOnGround(mobj->target) || mobj->target->player->pflags & PF_SPINNING)) P_SetTarget(&mobj->target, NULL); // Wait for them to hit the ground first + if (!mobj->target) // Still no target, aww. { // Reset the boss. @@ -5003,6 +4969,7 @@ static void P_Boss9Thinker(mobj_t *mobj) P_BossTargetPlayer(mobj, true); angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); // absolute angle angle = (angle-mobj->angle); // relative angle + if (angle < ANGLE_180) mobj->angle += angle/8; else @@ -5015,6 +4982,7 @@ static void P_Boss9Thinker(mobj_t *mobj) if (P_RandomRange(1,(dist>>FRACBITS)/16) == 1) break; } + if (spawner && dist) { mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); @@ -5154,11 +5122,8 @@ static void P_Boss9Thinker(mobj_t *mobj) mobj->momx = mobj->momy = 0; mobj->threshold--; if (!mobj->threshold) - { // Go into stun after dodge. - // from 3*TICRATE down to 1.25*TICRATE - //mobj->reactiontime = 5*TICRATE/4 + (FixedMul((7*TICRATE/4)<health-1)<info->spawnhealth-1)<>FRACBITS); - // from 3*TICRATE down to 2*TICRATE - mobj->reactiontime = 2*TICRATE + (FixedMul((1*TICRATE)<health-1)<info->spawnhealth-1)<>FRACBITS); + { + mobj->reactiontime = 2*TICRATE + (FixedMul((1*TICRATE)<health-1)<info->spawnhealth-1)<>FRACBITS); // Go into stun after dodge. mobj->flags |= MF_SPECIAL|MF_SHOOTABLE; P_SetMobjState(mobj, mobj->state->nextstate); } @@ -5181,10 +5146,12 @@ static void P_Boss9Thinker(mobj_t *mobj) mobj->angle -= FixedAngle(FixedMul(AngleFixed(InvAngle(mobj->movedir)),FixedDiv(mobj->reactiontime<angle += FixedAngle(FixedMul(AngleFixed(mobj->movedir),FixedDiv(mobj->reactiontime<reactiontime--; - if (!mobj->reactiontime) - // Out of stun. + + if (!mobj->reactiontime) // Out of stun. P_SetMobjState(mobj, mobj->state->nextstate); + return; } @@ -5334,7 +5301,6 @@ static void P_Boss9Thinker(mobj_t *mobj) mobj->angle += angle/8; else mobj->angle -= InvAngle(angle)/8; - //A_FaceTarget(mobj); // Check if we're being attacked if (!(mobj->target->player->pflags & (PF_JUMPED|PF_SPINNING) @@ -6079,17 +6045,12 @@ static void P_MobjScaleThink(mobj_t *mobj) else if (correctionType == 2) mobj->z -= mobj->height - oldheight; - if (mobj->scale == mobj->destscale) + if (mobj->scale == mobj->destscale && mobj->type == MT_EGGMOBILE_FIRE) + { /// \todo Lua hook for "reached destscale"? - switch(mobj->type) - { - case MT_EGGMOBILE_FIRE: - mobj->destscale = FRACUNIT; - mobj->scalespeed = FRACUNIT>>4; - break; - default: - break; - } + mobj->destscale = FRACUNIT; + mobj->scalespeed = FRACUNIT>>4; + } } // Special thinker for scenery objects @@ -6341,8 +6302,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) case MT_PLAYERARROW: if (mobj->target && mobj->target->health && mobj->target->player && !mobj->target->player->spectator - && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD - /*&& players[displayplayers[0]].mo && !players[displayplayers[0]].spectator*/) + && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD) { fixed_t scale = 3*mobj->target->scale; mobj->color = mobj->target->color; @@ -6740,22 +6700,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) case MT_SEED: mobj->momz = mobj->info->speed; break; - case MT_ROCKCRUMBLE1: - case MT_ROCKCRUMBLE2: - case MT_ROCKCRUMBLE3: - case MT_ROCKCRUMBLE4: - case MT_ROCKCRUMBLE5: - case MT_ROCKCRUMBLE6: - case MT_ROCKCRUMBLE7: - case MT_ROCKCRUMBLE8: - case MT_ROCKCRUMBLE9: - case MT_ROCKCRUMBLE10: - case MT_ROCKCRUMBLE11: - case MT_ROCKCRUMBLE12: - case MT_ROCKCRUMBLE13: - case MT_ROCKCRUMBLE14: - case MT_ROCKCRUMBLE15: - case MT_ROCKCRUMBLE16: + case MT_ROCKCRUMBLE1 ... MT_ROCKCRUMBLE16: if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) && mobj->state != &states[mobj->info->deathstate]) { @@ -6786,9 +6731,10 @@ static void P_MobjSceneryThink(mobj_t *mobj) } break; default: - if (mobj->fuse) - { // Scenery object fuse! Very basic! + if (mobj->fuse) // Scenery object fuse! Very basic! + { mobj->fuse--; + if (!mobj->fuse) { if (!LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse))) @@ -6878,6 +6824,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) i = P_RandomByte(); z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT); + for (j = 0; j < 2; j++) { const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK; @@ -6914,8 +6861,8 @@ static boolean P_MobjDeadThink(mobj_t *mobj) /// \todo Have the player's dead body completely finish its animation even if they've already respawned. if (!(mobj->flags2 & MF2_DONTDRAW)) { - if (!mobj->fuse) - { // Go away. + if (!mobj->fuse) // Go away. + { /// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it. mobj->momz = 0; if (mobj->player) @@ -6963,7 +6910,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) case MT_JAWZ_DUD: if (P_IsObjectOnGround(mobj)) P_SetMobjState(mobj, mobj->info->xdeathstate); - // fallthru + // fallthru case MT_JAWZ_SHIELD: mobj->flags2 ^= MF2_DONTDRAW; break; @@ -7041,8 +6988,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->z + mobj->height >= mobj->ceilingz : mobj->z <= mobj->floorz)) { - //P_RemoveMobj(mobj); - //return; mobj->fuse = TICRATE; } P_MobjCheckWater(mobj); @@ -7137,12 +7082,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (!playeringame[i] || !players[i].mo) continue; - if (players[i].mare != mobj->threshold) + if ((players[i].mare != mobj->threshold) || (players[i].health <= 1)) continue; - if (!(players[i].health > 1)) - continue; - fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); if (!(dist < shortest)) @@ -7193,67 +7135,76 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (!mobj->target // if you have no target || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now - { // then remove yourself as well! - P_RemoveMobj(mobj); + { + P_RemoveMobj(mobj); // then remove yourself as well! return false; } jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); - if (mobj->fuse == 56) // First one + switch (mobj->fuse) { - P_UnsetThingPosition(mobj); - mobj->x = jetx; - mobj->y = jety; - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(38*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(38*FRACUNIT, mobj->target->scale); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - else if (mobj->fuse == 57) - { - P_UnsetThingPosition(mobj); - mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - else if (mobj->fuse == 58) - { - P_UnsetThingPosition(mobj); - mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - else if (mobj->fuse == 59) - { - jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, -mobj->target->radius); - jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, -mobj->target->radius); - P_UnsetThingPosition(mobj); - mobj->x = jetx; - mobj->y = jety; - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height/2 + mobj->height/2; - else - mobj->z = mobj->target->z + mobj->target->height/2 - mobj->height/2; - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); + case 56: // First one + { + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(38*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(38*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + break; + case 57: + { + P_UnsetThingPosition(mobj); + mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + break; + case 58: + { + P_UnsetThingPosition(mobj); + mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + break; + case 59: + { + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, -mobj->target->radius); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, -mobj->target->radius); + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height/2 + mobj->height/2; + else + mobj->z = mobj->target->z + mobj->target->height/2 - mobj->height/2; + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_SetThingPosition(mobj); + } + break; + default: + break; } mobj->fuse++; } @@ -7571,6 +7522,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (G_RaceGametype() && mobj->tracer) { distaway = P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y); + if (distaway < distbarrier) { if (mobj->tracer->player) @@ -7739,8 +7691,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) // you can cycle through multiple states in a tic if (!mobj->tics) + { if (!P_SetMobjState(mobj, mobj->state->nextstate)) return false; // freed itself + } } P_UnsetThingPosition(mobj); @@ -7768,6 +7722,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { player_t *p = NULL; + if (mobj->target->target && mobj->target->target->player) p = mobj->target->target->player; else if (mobj->target->player) @@ -8585,7 +8540,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->z == mobj->movefactor) { mobj->extravalue1 = 1; - //S_StartSound(mobj, sfx_s1bb); } else mobj->momz = (mobj->info->speed/16) * P_MobjFlip(mobj); @@ -8714,6 +8668,7 @@ static void P_FlagFuseThink(mobj_t *mobj) x = mobj->spawnpoint->x << FRACBITS; y = mobj->spawnpoint->y << FRACBITS; ss = R_PointInSubsector(x, y); + if (mobj->spawnpoint->options & MTF_OBJECTFLIP) { z = ss->sector->ceilingheight - mobjinfo[mobj->type].height; @@ -8726,8 +8681,10 @@ static void P_FlagFuseThink(mobj_t *mobj) if (mobj->spawnpoint->options >> ZSHIFT) z += (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; } + flagmo = P_SpawnMobj(x, y, z, mobj->type); flagmo->spawnpoint = mobj->spawnpoint; + if (mobj->spawnpoint->options & MTF_OBJECTFLIP) { flagmo->eflags |= MFE_VERTICALFLIP; @@ -9124,7 +9081,9 @@ void P_MobjThinker(mobj_t *mobj) { if (!P_ZMovement(mobj)) return; // mobj was removed + P_CheckPosition(mobj, mobj->x, mobj->y); // Need this to pick up objects! + if (P_MobjWasRemoved(mobj)) return; } @@ -9141,9 +9100,9 @@ void P_MobjThinker(mobj_t *mobj) || mobj->type == MT_BIGTUMBLEWEED || mobj->type == MT_LITTLETUMBLEWEED || mobj->type == MT_CANNONBALLDECOR - || mobj->type == MT_FALLINGROCK) { + || mobj->type == MT_FALLINGROCK) + { P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly - //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); P_ButteredSlope(mobj); } @@ -9180,12 +9139,7 @@ void P_MobjThinker(mobj_t *mobj) switch (mobj->type) { - case MT_BOUNCEPICKUP: - case MT_RAILPICKUP: - case MT_AUTOPICKUP: - case MT_EXPLODEPICKUP: - case MT_SCATTERPICKUP: - case MT_GRENADEPICKUP: + case MT_BOUNCEPICKUP ... MT_GRENADEPICKUP: if (mobj->health == 0) // Fading tile { INT32 value = mobj->info->damage/10; @@ -9227,7 +9181,6 @@ boolean P_RailThinker(mobj_t *mobj) { if (!P_ZMovement(mobj)) return true; // mobj was removed - //P_CheckPosition(mobj, mobj->x, mobj->y); } return P_MobjWasRemoved(mobj) || (x == mobj->x && y == mobj->y && z == mobj->z); @@ -9257,6 +9210,9 @@ void P_PushableThinker(mobj_t *mobj) if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy)) P_TryMove(mobj, mobj->x, mobj->y, true); + if (!mobj) + return; + if (mobj->fuse == 1) // it would explode in the MobjThinker code { mobj_t *spawnmo; @@ -9281,12 +9237,16 @@ void P_PushableThinker(mobj_t *mobj) z = ss->sector->floorheight; spawnmo = P_SpawnMobj(x, y, z, mobj->type); - spawnmo->spawnpoint = mobj->spawnpoint; - P_UnsetThingPosition(spawnmo); - spawnmo->flags = mobj->flags; - P_SetThingPosition(spawnmo); - spawnmo->flags2 = mobj->flags2; - spawnmo->flags |= MF_PUSHABLE; + if (spawnmo) + { + spawnmo->spawnpoint = mobj->spawnpoint; + P_UnsetThingPosition(spawnmo); + spawnmo->flags = mobj->flags; + P_SetThingPosition(spawnmo); + spawnmo->flags2 = mobj->flags2; + spawnmo->flags |= MF_PUSHABLE; + } + P_RemoveMobj(mobj); break; default: @@ -9367,9 +9327,12 @@ void P_SceneryThinker(mobj_t *mobj) { if (!P_SceneryZMovement(mobj)) return; // mobj was removed + P_CheckPosition(mobj, mobj->x, mobj->y); // Need this to pick up objects! + if (P_MobjWasRemoved(mobj)) return; + mobj->floorz = tmfloorz; mobj->ceilingz = tmceilingz; } @@ -10691,9 +10654,6 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(mobj, mobj->destscale); P_FlashPal(p, 0, 0); // Resets - // Spawn with a pity shield if necessary. - //P_DoPityCheck(p); - p->grieftime = 0; p->hitemtimer = 0; p->hitemvictim = 255; @@ -10933,7 +10893,6 @@ void P_MovePlayerToStarpost(INT32 playernum) else z = (p->starpostz<starpostz + 128) << FRACBITS; // reverse gravity exists, pls mobj->player->kartstuff[k_starpostflip] = 0; if (z < floor) @@ -10953,9 +10912,6 @@ void P_MovePlayerToStarpost(INT32 playernum) p->kartstuff[k_waypoint] = p->kartstuff[k_starpostwp]; // SRB2kart P_AfterPlayerSpawn(playernum); - - //if (!(netgame || multiplayer)) - // leveltime = p->starposttime; } #define MAXHUNTEMERALDS 64 @@ -10997,51 +10953,44 @@ void P_SpawnMapThing(mapthing_t *mthing) } // count deathmatch start positions - if (mthing->type == 33) + switch (mthing->type) { - if (numdmstarts < MAX_DM_STARTS) - { - deathmatchstarts[numdmstarts] = mthing; - mthing->type = 0; - numdmstarts++; - } - return; - } - - else if (mthing->type == 34) // Red CTF Starts - { - if (numredctfstarts < MAXPLAYERS) - { - redctfstarts[numredctfstarts] = mthing; - mthing->type = 0; - numredctfstarts++; - } - return; - } - - else if (mthing->type == 35) // Blue CTF Starts - { - if (numbluectfstarts < MAXPLAYERS) - { - bluectfstarts[numbluectfstarts] = mthing; - mthing->type = 0; - numbluectfstarts++; - } - return; - } - - else if (mthing->type == 750) // Slope vertex point (formerly chaos spawn) - return; - - else if (mthing->type == 300 // Ring - || mthing->type == 308 || mthing->type == 309 // Team Rings - || mthing->type == 1706 // Nights Wing - || (mthing->type >= 600 && mthing->type <= 609) // Placement patterns - || mthing->type == 1705 || mthing->type == 1713 // NiGHTS Hoops - || mthing->type == 1800) // Mario Coin - { - // Don't spawn hoops, wings, or rings yet! - return; + case 33: + if (numdmstarts < MAX_DM_STARTS) + { + deathmatchstarts[numdmstarts] = mthing; + mthing->type = 0; + numdmstarts++; + } + return; + case 34: // Red CTF Starts + if (numredctfstarts < MAXPLAYERS) + { + redctfstarts[numredctfstarts] = mthing; + mthing->type = 0; + numredctfstarts++; + } + return; + case 35: // Blue CTF Starts + if (numbluectfstarts < MAXPLAYERS) + { + bluectfstarts[numbluectfstarts] = mthing; + mthing->type = 0; + numbluectfstarts++; + } + return; + case 300: // Ring + case 308: + case 309: // Team Rings + case 600 ... 609: // Placement patterns + case 750: // Slope vertex point (formerly chaos spawn) + case 1705: + case 1706: // Nights Wing + case 1713: // NiGHTS Hoops + case 1800: // Mario Coin + return; // Don't spawn hoops, wings, or rings yet! + default: + break; } // check for players specially @@ -11061,28 +11010,35 @@ void P_SpawnMapThing(mapthing_t *mthing) return; } + // If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints. if (metalrecording && mthing->type == mobjinfo[MT_METALSONIC_RACE].doomednum) - { // If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints. + { playerstarts[0] = mthing; return; } // find which type to spawn for (i = 0; i < NUMMOBJTYPES; i++) + { if (mthing->type == mobjinfo[i].doomednum) break; + } if (i == NUMMOBJTYPES) { if (mthing->type == 3328) // 3D Mode start Thing return; + CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); + i = MT_UNKNOWN; } if (metalrecording) // Metal Sonic can't use these things. + { if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_EMMY || i == MT_STARPOST) return; + } if (i >= MT_EMERALD1 && i <= MT_EMERALD7) // Pickupable Emeralds { @@ -11097,8 +11053,10 @@ void P_SpawnMapThing(mapthing_t *mthing) } if (!G_BattleGametype() || !cv_specialrings.value) + { if (P_WeaponOrPanel(i)) return; // Don't place weapons/panels in non-ringslinger modes + } if (i == MT_EMERHUNT) { @@ -11116,60 +11074,71 @@ void P_SpawnMapThing(mapthing_t *mthing) if (i == MT_EMERALDSPAWN) { - if (!cv_powerstones.value) - return; - - if (!G_BattleGametype()) + if (!cv_powerstones.value || !G_BattleGametype()) return; runemeraldmanager = true; } if (!G_RaceGametype()) // No enemies in match or CTF modes + { if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS)) return; - - // Set powerup boxes to user settings for competition. - if (gametype == GT_COMPETITION) - { - if ((mobjinfo[i].flags & MF_MONITOR) && cv_competitionboxes.value) // not Normal - { - if (cv_competitionboxes.value == 1) // Random - i = MT_QUESTIONBOX; - else if (cv_competitionboxes.value == 2) // Teleports - i = MT_MIXUPBOX; - else if (cv_competitionboxes.value == 3) // None - return; // Don't spawn! - } } - // Set powerup boxes to user settings for other netplay modes - else if (gametype != GT_COOP) + // Set powerup boxes to user settings for competition. + if (gametype == GT_COMPETITION && cv_competitionboxes.value && (mobjinfo[i].flags & MF_MONITOR)) // not Normal { - if ((mobjinfo[i].flags & MF_MONITOR) && cv_matchboxes.value) // not Normal + switch (cv_competitionboxes.value) { - if (cv_matchboxes.value == 1) // Random + case 1: // Random i = MT_QUESTIONBOX; - else if (cv_matchboxes.value == 3) // Don't spawn - return; - else // cv_matchboxes.value == 2, Non-Random - { + break; + case 2: // Teleports + i = MT_MIXUPBOX; + break; + case 3: // None + return; // Don't spawn! + default: + break; + } + } + // Set powerup boxes to user settings for other netplay modes + else if (gametype != GT_COOP && cv_matchboxes.value && (mobjinfo[i].flags & MF_MONITOR)) // not Normal + { + switch (cv_matchboxes.value) + { + case 1: // Random + i = MT_QUESTIONBOX; + break; + case 3: // None + return; // Don't spawn! + default: if (i == MT_QUESTIONBOX) return; // don't spawn in Non-Random - mthing->options &= ~(MTF_AMBUSH|MTF_OBJECTSPECIAL); // no random respawning! - } + break; } } if (gametype != GT_CTF) // CTF specific things { - if (i == MT_BLUETEAMRING || i == MT_REDTEAMRING) - i = MT_RING; - else if (i == MT_BLUERINGBOX || i == MT_REDRINGBOX) - i = MT_SUPERRINGBOX; - else if (i == MT_BLUEFLAG || i == MT_REDFLAG) - return; // No flags in non-CTF modes! + switch (i) + { + case MT_BLUETEAMRING: + case MT_REDTEAMRING: + i = MT_RING; + break; + case MT_BLUERINGBOX: + case MT_REDRINGBOX: + i = MT_SUPERRINGBOX; + break; + case MT_BLUEFLAG: + case MT_REDFLAG: + return; // No flags in non-CTF modes! + default: + break; + } } else { @@ -11266,12 +11235,25 @@ void P_SpawnMapThing(mapthing_t *mthing) // offsetting if (mthing->options >> ZSHIFT) offset = ((mthing->options >> ZSHIFT) << FRACBITS); - else if (i == MT_CRAWLACOMMANDER || i == MT_DETON || i == MT_JETTBOMBER || i == MT_JETTGUNNER || i == MT_EGGMOBILE2) - offset = 33*FRACUNIT; - else if (i == MT_EGGMOBILE) - offset = 128*FRACUNIT; - else if (i == MT_GOLDBUZZ || i == MT_REDBUZZ) - offset = 288*FRACUNIT; + else switch (i) + { + case MT_CRAWLACOMMANDER: + case MT_DETON: + case MT_JETTBOMBER: + case MT_JETTGUNNER: + case MT_EGGMOBILE2: + offset = 33*FRACUNIT; + break; + case MT_EGGMOBILE: + offset = 128*FRACUNIT; + break; + case MT_GOLDBUZZ: + case MT_REDBUZZ: + offset = 288*FRACUNIT; + break; + default: + break; + } // applying offsets! (if any) if (flip) -- 2.54.0 From bcec8b98f7e2532b2c0dbbecab2959e4154b57ac Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 28 May 2025 18:24:16 +0200 Subject: [PATCH 6/9] make the game c23 compatible properly + some cleanup and removal of some redundant checks --- src/am_map.c | 2 + src/d_netcmd.c | 8 +- src/d_think.h | 9 +- src/dehacked.c | 435 ++-- src/discord.c | 2 +- src/doomtype.h | 24 +- src/g_game.c | 63 +- src/hardware/hw_cache.c | 2 +- src/info.c | 5377 +++++++++++++++++++-------------------- src/info.h | 407 ++- src/k_kart.c | 42 +- src/lua_infolib.c | 14 +- src/lua_mathlib.c | 2 +- src/lua_script.c | 13 +- src/lua_thinkerlib.c | 8 +- src/m_cheat.c | 2 +- src/m_menu.c | 7 +- src/m_perfstats.c | 16 +- src/p_ceilng.c | 4 +- src/p_enemy.c | 1891 +++++++------- src/p_floor.c | 14 +- src/p_inter.c | 16 +- src/p_lights.c | 12 +- src/p_local.h | 2 +- src/p_map.c | 4 +- src/p_mobj.c | 110 +- src/p_polyobj.c | 26 +- src/p_saveg.c | 134 +- src/p_spec.c | 67 +- src/p_tick.c | 30 +- src/p_user.c | 26 +- src/r_data.c | 2 +- src/s_sound.c | 3 +- src/sdl/mixer_sound.c | 10 +- 34 files changed, 4429 insertions(+), 4355 deletions(-) diff --git a/src/am_map.c b/src/am_map.c index f91273e8b..1478b37f9 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -318,11 +318,13 @@ static void AM_initVariables(void) break; plr = &players[pnum]; + if (plr != NULL && plr->mo != NULL) { m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2; m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2; } + AM_changeWindowLoc(); // for saving & restoring diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5b8a8c18b..f09aad652 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2115,14 +2115,18 @@ static INT32 LookupPlayer(const char *s) static INT32 FindPlayerByPlace(INT32 place) { INT32 playernum; + for (playernum = 0; playernum < MAXPLAYERS; ++playernum) - if (playeringame[playernum]) { + if (!playeringame[playernum]) + continue; + if (players[playernum].kartstuff[k_position] == place) { return playernum; } } + return -1; } @@ -5674,7 +5678,7 @@ static void Command_Archivetest_f(void) // assign mobjnum i = 1; for (th = thinkercap.next; th != &thinkercap; th = th->next) - if (th->function.acp1 == (actionf_p1)P_MobjThinker) + if (th->function == (actionf_p1)P_MobjThinker) ((mobj_t *)th)->mobjnum = i++; // allocate buffer diff --git a/src/d_think.h b/src/d_think.h index 8177f464d..1ef2577dc 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -28,18 +28,11 @@ // To compile this as "ANSI C with classes" we will need to handle the various // action functions cleanly. // -typedef void (*actionf_v)(); typedef void (*actionf_p1)(void *); -typedef union -{ - actionf_v acv; - actionf_p1 acp1; -} actionf_t; - // Historically, "think_t" is yet another function pointer to a routine // to handle an actor. -typedef actionf_t think_t; +typedef actionf_p1 think_t; // Doubly linked list of actors. typedef struct thinker_s diff --git a/src/dehacked.c b/src/dehacked.c index f0e2583d8..c5412e29f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1416,211 +1416,212 @@ static void readhuditem(MYFILE *f, INT32 num) // DO NOT FORGET TO SYNC THIS LIST WITH THE ACTIONNUM ENUM IN INFO.H actionpointer_t actionpointers[] = { - {{A_Explode}, "A_EXPLODE"}, - {{A_Pain}, "A_PAIN"}, - {{A_Fall}, "A_FALL"}, - {{A_MonitorPop}, "A_MONITORPOP"}, - {{A_Look}, "A_LOOK"}, - {{A_Chase}, "A_CHASE"}, - {{A_FaceStabChase}, "A_FACESTABCHASE"}, - {{A_FaceTarget}, "A_FACETARGET"}, - {{A_FaceTracer}, "A_FACETRACER"}, - {{A_Scream}, "A_SCREAM"}, - {{A_BossDeath}, "A_BOSSDEATH"}, - {{A_CustomPower}, "A_CUSTOMPOWER"}, - {{A_GiveWeapon}, "A_GIVEWEAPON"}, - {{A_RingShield}, "A_RINGSHIELD"}, - {{A_RingBox}, "A_RINGBOX"}, - {{A_Invincibility}, "A_INVINCIBILITY"}, - {{A_SuperSneakers}, "A_SUPERSNEAKERS"}, - {{A_BunnyHop}, "A_BUNNYHOP"}, - {{A_BubbleSpawn}, "A_BUBBLESPAWN"}, - {{A_FanBubbleSpawn}, "A_FANBUBBLESPAWN"}, - {{A_BubbleRise}, "A_BUBBLERISE"}, - {{A_BubbleCheck}, "A_BUBBLECHECK"}, - {{A_AwardScore}, "A_AWARDSCORE"}, - {{A_ExtraLife}, "A_EXTRALIFE"}, - {{A_BombShield}, "A_BOMBSHIELD"}, - {{A_JumpShield}, "A_JUMPSHIELD"}, - {{A_WaterShield}, "A_WATERSHIELD"}, - {{A_ForceShield}, "A_FORCESHIELD"}, - {{A_PityShield}, "A_PITYSHIELD"}, - {{A_GravityBox}, "A_GRAVITYBOX"}, - {{A_ScoreRise}, "A_SCORERISE"}, - {{A_ParticleSpawn}, "A_PARTICLESPAWN"}, - {{A_AttractChase}, "A_ATTRACTCHASE"}, - {{A_DropMine}, "A_DROPMINE"}, - {{A_FishJump}, "A_FISHJUMP"}, - {{A_ThrownRing}, "A_THROWNRING"}, - {{A_GrenadeRing}, "A_GRENADERING"}, // SRB2kart - {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, - {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, - {{A_SignPlayer}, "A_SIGNPLAYER"}, - {{A_OverlayThink}, "A_OVERLAYTHINK"}, - {{A_JetChase}, "A_JETCHASE"}, - {{A_JetbThink}, "A_JETBTHINK"}, - {{A_JetgThink}, "A_JETGTHINK"}, - {{A_JetgShoot}, "A_JETGSHOOT"}, - {{A_ShootBullet}, "A_SHOOTBULLET"}, - {{A_MinusDigging}, "A_MINUSDIGGING"}, - {{A_MinusPopup}, "A_MINUSPOPUP"}, - {{A_MinusCheck}, "A_MINUSCHECK"}, - {{A_ChickenCheck}, "A_CHICKENCHECK"}, - {{A_MouseThink}, "A_MOUSETHINK"}, - {{A_DetonChase}, "A_DETONCHASE"}, - {{A_CapeChase}, "A_CAPECHASE"}, - {{A_RotateSpikeBall}, "A_ROTATESPIKEBALL"}, - {{A_SlingAppear}, "A_SLINGAPPEAR"}, - {{A_MaceRotate}, "A_MACEROTATE"}, - {{A_UnidusBall}, "A_UNIDUSBALL"}, - {{A_RockSpawn}, "A_ROCKSPAWN"}, - {{A_SetFuse}, "A_SETFUSE"}, - {{A_CrawlaCommanderThink}, "A_CRAWLACOMMANDERTHINK"}, - {{A_SmokeTrailer}, "A_SMOKETRAILER"}, - {{A_RingExplode}, "A_RINGEXPLODE"}, - {{A_OldRingExplode}, "A_OLDRINGEXPLODE"}, - {{A_MixUp}, "A_MIXUP"}, - {{A_RecyclePowers}, "A_RECYCLEPOWERS"}, - {{A_Boss1Chase}, "A_BOSS1CHASE"}, - {{A_FocusTarget}, "A_FOCUSTARGET"}, - {{A_Boss2Chase}, "A_BOSS2CHASE"}, - {{A_Boss2Pogo}, "A_BOSS2POGO"}, - {{A_BossZoom}, "A_BOSSZOOM"}, - {{A_BossScream}, "A_BOSSSCREAM"}, - {{A_Boss2TakeDamage}, "A_BOSS2TAKEDAMAGE"}, - {{A_Boss7Chase}, "A_BOSS7CHASE"}, - {{A_GoopSplat}, "A_GOOPSPLAT"}, - {{A_Boss2PogoSFX}, "A_BOSS2POGOSFX"}, - {{A_Boss2PogoTarget}, "A_BOSS2POGOTARGET"}, - {{A_BossJetFume}, "A_BOSSJETFUME"}, - {{A_EggmanBox}, "A_EGGMANBOX"}, - {{A_TurretFire}, "A_TURRETFIRE"}, - {{A_SuperTurretFire}, "A_SUPERTURRETFIRE"}, - {{A_TurretStop}, "A_TURRETSTOP"}, - {{A_JetJawRoam}, "A_JETJAWROAM"}, - {{A_JetJawChomp}, "A_JETJAWCHOMP"}, - {{A_PointyThink}, "A_POINTYTHINK"}, - {{A_CheckBuddy}, "A_CHECKBUDDY"}, - {{A_HoodThink}, "A_HOODTHINK"}, - {{A_ArrowCheck}, "A_ARROWCHECK"}, - {{A_SnailerThink}, "A_SNAILERTHINK"}, - {{A_SharpChase}, "A_SHARPCHASE"}, - {{A_SharpSpin}, "A_SHARPSPIN"}, - {{A_VultureVtol}, "A_VULTUREVTOL"}, - {{A_VultureCheck}, "A_VULTURECHECK"}, - {{A_SkimChase}, "A_SKIMCHASE"}, - {{A_1upThinker}, "A_1UPTHINKER"}, - {{A_SkullAttack}, "A_SKULLATTACK"}, - {{A_LobShot}, "A_LOBSHOT"}, - {{A_FireShot}, "A_FIRESHOT"}, - {{A_SuperFireShot}, "A_SUPERFIRESHOT"}, - {{A_BossFireShot}, "A_BOSSFIRESHOT"}, - {{A_Boss7FireMissiles}, "A_BOSS7FIREMISSILES"}, - {{A_Boss1Laser}, "A_BOSS1LASER"}, - {{A_Boss4Reverse}, "A_BOSS4REVERSE"}, - {{A_Boss4SpeedUp}, "A_BOSS4SPEEDUP"}, - {{A_Boss4Raise}, "A_BOSS4RAISE"}, - {{A_SparkFollow}, "A_SPARKFOLLOW"}, - {{A_BuzzFly}, "A_BUZZFLY"}, - {{A_GuardChase}, "A_GUARDCHASE"}, - {{A_EggShield}, "A_EGGSHIELD"}, - {{A_SetReactionTime}, "A_SETREACTIONTIME"}, - {{A_Boss1Spikeballs}, "A_BOSS1SPIKEBALLS"}, - {{A_Boss3TakeDamage}, "A_BOSS3TAKEDAMAGE"}, - {{A_Boss3Path}, "A_BOSS3PATH"}, - {{A_LinedefExecute}, "A_LINEDEFEXECUTE"}, - {{A_PlaySeeSound}, "A_PLAYSEESOUND"}, - {{A_PlayAttackSound}, "A_PLAYATTACKSOUND"}, - {{A_PlayActiveSound}, "A_PLAYACTIVESOUND"}, - {{A_SpawnObjectAbsolute}, "A_SPAWNOBJECTABSOLUTE"}, - {{A_SpawnObjectRelative}, "A_SPAWNOBJECTRELATIVE"}, - {{A_ChangeAngleRelative}, "A_CHANGEANGLERELATIVE"}, - {{A_ChangeAngleAbsolute}, "A_CHANGEANGLEABSOLUTE"}, - {{A_PlaySound}, "A_PLAYSOUND"}, - {{A_FindTarget}, "A_FINDTARGET"}, - {{A_FindTracer}, "A_FINDTRACER"}, - {{A_SetTics}, "A_SETTICS"}, - {{A_SetRandomTics}, "A_SETRANDOMTICS"}, - {{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"}, - {{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"}, - {{A_MoveRelative}, "A_MOVERELATIVE"}, - {{A_MoveAbsolute}, "A_MOVEABSOLUTE"}, - {{A_Thrust}, "A_THRUST"}, - {{A_ZThrust}, "A_ZTHRUST"}, - {{A_SetTargetsTarget}, "A_SETTARGETSTARGET"}, - {{A_SetObjectFlags}, "A_SETOBJECTFLAGS"}, - {{A_SetObjectFlags2}, "A_SETOBJECTFLAGS2"}, - {{A_RandomState}, "A_RANDOMSTATE"}, - {{A_RandomStateRange}, "A_RANDOMSTATERANGE"}, - {{A_DualAction}, "A_DUALACTION"}, - {{A_RemoteAction}, "A_REMOTEACTION"}, - {{A_ToggleFlameJet}, "A_TOGGLEFLAMEJET"}, - {{A_ItemPop}, "A_ITEMPOP"}, // SRB2kart - {{A_JawzChase}, "A_JAWZCHASE"}, // SRB2kart - {{A_JawzExplode}, "A_JAWZEXPLODE"}, // SRB2kart - {{A_SPBChase}, "A_SPBCHASE"}, // SRB2kart - {{A_MineExplode}, "A_MINEEXPLODE"}, // SRB2kart - {{A_BallhogExplode}, "A_BALLHOGEXPLODE"}, // SRB2kart - {{A_LightningFollowPlayer},"A_LIGHTNINGFOLLOWPLAYER"}, //SRB2kart - {{A_FZBoomFlash}, "A_FZBOOMFLASH"}, //SRB2kart - {{A_FZBoomSmoke}, "A_FZBOOMSMOKE"}, //SRB2kart - {{A_RandomShadowFrame}, "A_RANDOMSHADOWFRAME"}, //SRB2kart - {{A_RoamingShadowThinker}, "A_ROAMINGSHADOWTHINKER"}, //SRB2kart - {{A_MayonakaArrow}, "A_MAYONAKAARROW"}, //SRB2kart - {{A_ReaperThinker}, "A_REAPERTHINKER"}, //SRB2kart - {{A_MementosTPParticles}, "A_MEMENTOSTPPARTICLES"}, //SRB2kart - {{A_FlameParticle}, "A_FLAMEPARTICLE"}, // SRB2kart - {{A_OrbitNights}, "A_ORBITNIGHTS"}, - {{A_GhostMe}, "A_GHOSTME"}, - {{A_SetObjectState}, "A_SETOBJECTSTATE"}, - {{A_SetObjectTypeState}, "A_SETOBJECTTYPESTATE"}, - {{A_KnockBack}, "A_KNOCKBACK"}, - {{A_PushAway}, "A_PUSHAWAY"}, - {{A_RingDrain}, "A_RINGDRAIN"}, - {{A_SplitShot}, "A_SPLITSHOT"}, - {{A_MissileSplit}, "A_MISSILESPLIT"}, - {{A_MultiShot}, "A_MULTISHOT"}, - {{A_InstaLoop}, "A_INSTALOOP"}, - {{A_Custom3DRotate}, "A_CUSTOM3DROTATE"}, - {{A_SearchForPlayers}, "A_SEARCHFORPLAYERS"}, - {{A_CheckRandom}, "A_CHECKRANDOM"}, - {{A_CheckTargetRings}, "A_CHECKTARGETRINGS"}, - {{A_CheckRings}, "A_CHECKRINGS"}, - {{A_CheckTotalRings}, "A_CHECKTOTALRINGS"}, - {{A_CheckHealth}, "A_CHECKHEALTH"}, - {{A_CheckRange}, "A_CHECKRANGE"}, - {{A_CheckHeight}, "A_CHECKHEIGHT"}, - {{A_CheckTrueRange}, "A_CHECKTRUERANGE"}, - {{A_CheckThingCount}, "A_CHECKTHINGCOUNT"}, - {{A_CheckAmbush}, "A_CHECKAMBUSH"}, - {{A_CheckCustomValue}, "A_CHECKCUSTOMVALUE"}, - {{A_CheckCusValMemo}, "A_CHECKCUSVALMEMO"}, - {{A_SetCustomValue}, "A_SETCUSTOMVALUE"}, - {{A_UseCusValMemo}, "A_USECUSVALMEMO"}, - {{A_RelayCustomValue}, "A_RELAYCUSTOMVALUE"}, - {{A_CusValAction}, "A_CUSVALACTION"}, - {{A_ForceStop}, "A_FORCESTOP"}, - {{A_ForceWin}, "A_FORCEWIN"}, - {{A_SpikeRetract}, "A_SPIKERETRACT"}, - {{A_InfoState}, "A_INFOSTATE"}, - {{A_Repeat}, "A_REPEAT"}, - {{A_SetScale}, "A_SETSCALE"}, - {{A_RemoteDamage}, "A_REMOTEDAMAGE"}, - {{A_HomingChase}, "A_HOMINGCHASE"}, - {{A_TrapShot}, "A_TRAPSHOT"}, - {{A_VileTarget}, "A_VILETARGET"}, - {{A_VileAttack}, "A_VILEATTACK"}, - {{A_VileFire}, "A_VILEFIRE"}, - {{A_BrakChase}, "A_BRAKCHASE"}, - {{A_BrakFireShot}, "A_BRAKFIRESHOT"}, - {{A_BrakLobShot}, "A_BRAKLOBSHOT"}, - {{A_NapalmScatter}, "A_NAPALMSCATTER"}, - {{A_SpawnFreshCopy}, "A_SPAWNFRESHCOPY"}, + {A_Explode, "A_EXPLODE"}, + {A_Pain, "A_PAIN"}, + {A_Fall, "A_FALL"}, + {A_MonitorPop, "A_MONITORPOP"}, + {A_Look, "A_LOOK"}, + {A_Chase, "A_CHASE"}, + {A_FaceStabChase, "A_FACESTABCHASE"}, + {A_FaceTarget, "A_FACETARGET"}, + {A_FaceTracer, "A_FACETRACER"}, + {A_Scream, "A_SCREAM"}, + {A_BossDeath, "A_BOSSDEATH"}, + {A_CustomPower, "A_CUSTOMPOWER"}, + {A_GiveWeapon, "A_GIVEWEAPON"}, + {A_RingShield, "A_RINGSHIELD"}, + {A_RingBox, "A_RINGBOX"}, + {A_Invincibility, "A_INVINCIBILITY"}, + {A_SuperSneakers, "A_SUPERSNEAKERS"}, + {A_BunnyHop, "A_BUNNYHOP"}, + {A_BubbleSpawn, "A_BUBBLESPAWN"}, + {A_FanBubbleSpawn, "A_FANBUBBLESPAWN"}, + {A_BubbleRise, "A_BUBBLERISE"}, + {A_BubbleCheck, "A_BUBBLECHECK"}, + {A_AwardScore, "A_AWARDSCORE"}, + {A_ExtraLife, "A_EXTRALIFE"}, + {A_BombShield, "A_BOMBSHIELD"}, + {A_JumpShield, "A_JUMPSHIELD"}, + {A_WaterShield, "A_WATERSHIELD"}, + {A_ForceShield, "A_FORCESHIELD"}, + {A_PityShield, "A_PITYSHIELD"}, + {A_GravityBox, "A_GRAVITYBOX"}, + {A_ScoreRise, "A_SCORERISE"}, + {A_ParticleSpawn, "A_PARTICLESPAWN"}, + {A_AttractChase, "A_ATTRACTCHASE"}, + {A_DropMine, "A_DROPMINE"}, + {A_FishJump, "A_FISHJUMP"}, + {A_ThrownRing, "A_THROWNRING"}, + {A_GrenadeRing, "A_GRENADERING"}, // SRB2kart + {A_SetSolidSteam, "A_SETSOLIDSTEAM"}, + {A_UnsetSolidSteam, "A_UNSETSOLIDSTEAM"}, + {A_SignPlayer, "A_SIGNPLAYER"}, + {A_OverlayThink, "A_OVERLAYTHINK"}, + {A_JetChase, "A_JETCHASE"}, + {A_JetbThink, "A_JETBTHINK"}, + {A_JetgThink, "A_JETGTHINK"}, + {A_JetgShoot, "A_JETGSHOOT"}, + {A_ShootBullet, "A_SHOOTBULLET"}, + {A_MinusDigging, "A_MINUSDIGGING"}, + {A_MinusPopup, "A_MINUSPOPUP"}, + {A_MinusCheck, "A_MINUSCHECK"}, + {A_ChickenCheck, "A_CHICKENCHECK"}, + {A_MouseThink, "A_MOUSETHINK"}, + {A_DetonChase, "A_DETONCHASE"}, + {A_CapeChase, "A_CAPECHASE"}, + {A_RotateSpikeBall, "A_ROTATESPIKEBALL"}, + {A_SlingAppear, "A_SLINGAPPEAR"}, + {A_MaceRotate, "A_MACEROTATE"}, + {A_UnidusBall, "A_UNIDUSBALL"}, + {A_RockSpawn, "A_ROCKSPAWN"}, + {A_SetFuse, "A_SETFUSE"}, + {A_CrawlaCommanderThink, "A_CRAWLACOMMANDERTHINK"}, + {A_SmokeTrailer, "A_SMOKETRAILER"}, + {A_RingExplode, "A_RINGEXPLODE"}, + {A_OldRingExplode, "A_OLDRINGEXPLODE"}, + {A_MixUp, "A_MIXUP"}, + {A_RecyclePowers, "A_RECYCLEPOWERS"}, + {A_Boss1Chase, "A_BOSS1CHASE"}, + {A_FocusTarget, "A_FOCUSTARGET"}, + {A_Boss2Chase, "A_BOSS2CHASE"}, + {A_Boss2Pogo, "A_BOSS2POGO"}, + {A_BossZoom, "A_BOSSZOOM"}, + {A_BossScream, "A_BOSSSCREAM"}, + {A_Boss2TakeDamage, "A_BOSS2TAKEDAMAGE"}, + {A_Boss7Chase, "A_BOSS7CHASE"}, + {A_GoopSplat, "A_GOOPSPLAT"}, + {A_Boss2PogoSFX, "A_BOSS2POGOSFX"}, + {A_Boss2PogoTarget, "A_BOSS2POGOTARGET"}, + {A_BossJetFume, "A_BOSSJETFUME"}, + {A_EggmanBox, "A_EGGMANBOX"}, + {A_TurretFire, "A_TURRETFIRE"}, + {A_SuperTurretFire, "A_SUPERTURRETFIRE"}, + {A_TurretStop, "A_TURRETSTOP"}, + {A_JetJawRoam, "A_JETJAWROAM"}, + {A_JetJawChomp, "A_JETJAWCHOMP"}, + {A_PointyThink, "A_POINTYTHINK"}, + {A_CheckBuddy, "A_CHECKBUDDY"}, + {A_HoodThink, "A_HOODTHINK"}, + {A_ArrowCheck, "A_ARROWCHECK"}, + {A_SnailerThink, "A_SNAILERTHINK"}, + {A_SharpChase, "A_SHARPCHASE"}, + {A_SharpSpin, "A_SHARPSPIN"}, + {A_VultureVtol, "A_VULTUREVTOL"}, + {A_VultureCheck, "A_VULTURECHECK"}, + {A_SkimChase, "A_SKIMCHASE"}, + {A_1upThinker, "A_1UPTHINKER"}, + {A_SkullAttack, "A_SKULLATTACK"}, + {A_LobShot, "A_LOBSHOT"}, + {A_FireShot, "A_FIRESHOT"}, + {A_SuperFireShot, "A_SUPERFIRESHOT"}, + {A_BossFireShot, "A_BOSSFIRESHOT"}, + {A_Boss7FireMissiles, "A_BOSS7FIREMISSILES"}, + {A_Boss1Laser, "A_BOSS1LASER"}, + {A_Boss4Reverse, "A_BOSS4REVERSE"}, + {A_Boss4SpeedUp, "A_BOSS4SPEEDUP"}, + {A_Boss4Raise, "A_BOSS4RAISE"}, + {A_SparkFollow, "A_SPARKFOLLOW"}, + {A_BuzzFly, "A_BUZZFLY"}, + {A_GuardChase, "A_GUARDCHASE"}, + {A_EggShield, "A_EGGSHIELD"}, + {A_SetReactionTime, "A_SETREACTIONTIME"}, + {A_Boss1Spikeballs, "A_BOSS1SPIKEBALLS"}, + {A_Boss3TakeDamage, "A_BOSS3TAKEDAMAGE"}, + {A_Boss3Path, "A_BOSS3PATH"}, + {A_LinedefExecute, "A_LINEDEFEXECUTE"}, + {A_PlaySeeSound, "A_PLAYSEESOUND"}, + {A_PlayAttackSound, "A_PLAYATTACKSOUND"}, + {A_PlayActiveSound, "A_PLAYACTIVESOUND"}, + {A_SpawnObjectAbsolute, "A_SPAWNOBJECTABSOLUTE"}, + {A_SpawnObjectRelative, "A_SPAWNOBJECTRELATIVE"}, + {A_ChangeAngleRelative, "A_CHANGEANGLERELATIVE"}, + {A_ChangeAngleAbsolute, "A_CHANGEANGLEABSOLUTE"}, + {A_PlaySound, "A_PLAYSOUND"}, + {A_FindTarget, "A_FINDTARGET"}, + {A_FindTracer, "A_FINDTRACER"}, + {A_SetTics, "A_SETTICS"}, + {A_SetRandomTics, "A_SETRANDOMTICS"}, + {A_ChangeColorRelative, "A_CHANGECOLORRELATIVE"}, + {A_ChangeColorAbsolute, "A_CHANGECOLORABSOLUTE"}, + {A_MoveRelative, "A_MOVERELATIVE"}, + {A_MoveAbsolute, "A_MOVEABSOLUTE"}, + {A_Thrust, "A_THRUST"}, + {A_ZThrust, "A_ZTHRUST"}, + {A_SetTargetsTarget, "A_SETTARGETSTARGET"}, + {A_SetObjectFlags, "A_SETOBJECTFLAGS"}, + {A_SetObjectFlags2, "A_SETOBJECTFLAGS2"}, + {A_RandomState, "A_RANDOMSTATE"}, + {A_RandomStateRange, "A_RANDOMSTATERANGE"}, + {A_DualAction, "A_DUALACTION"}, + {A_RemoteAction, "A_REMOTEACTION"}, + {A_ToggleFlameJet, "A_TOGGLEFLAMEJET"}, + {A_ItemPop, "A_ITEMPOP"}, // SRB2kart + {A_JawzChase, "A_JAWZCHASE"}, // SRB2kart + {A_JawzExplode, "A_JAWZEXPLODE"}, // SRB2kart + {A_SPBChase, "A_SPBCHASE"}, // SRB2kart + {A_MineExplode, "A_MINEEXPLODE"}, // SRB2kart + {A_BallhogExplode, "A_BALLHOGEXPLODE"}, // SRB2kart + {A_LightningFollowPlayer,"A_LIGHTNINGFOLLOWPLAYER"}, //SRB2kart + {A_FZBoomFlash, "A_FZBOOMFLASH"}, //SRB2kart + {A_FZBoomSmoke, "A_FZBOOMSMOKE"}, //SRB2kart + {A_RandomShadowFrame, "A_RANDOMSHADOWFRAME"}, //SRB2kart + {A_RoamingShadowThinker, "A_ROAMINGSHADOWTHINKER"}, //SRB2kart + {A_MayonakaArrow, "A_MAYONAKAARROW"}, //SRB2kart + {A_ReaperThinker, "A_REAPERTHINKER"}, //SRB2kart + {A_MementosTPParticles, "A_MEMENTOSTPPARTICLES"}, //SRB2kart + {A_FlameParticle, "A_FLAMEPARTICLE"}, // SRB2kart + {A_OrbitNights, "A_ORBITNIGHTS"}, + {A_GhostMe, "A_GHOSTME"}, + {A_SetObjectState, "A_SETOBJECTSTATE"}, + {A_SetObjectTypeState, "A_SETOBJECTTYPESTATE"}, + {A_KnockBack, "A_KNOCKBACK"}, + {A_PushAway, "A_PUSHAWAY"}, + {A_RingDrain, "A_RINGDRAIN"}, + {A_SplitShot, "A_SPLITSHOT"}, + {A_MissileSplit, "A_MISSILESPLIT"}, + {A_MultiShot, "A_MULTISHOT"}, + {A_InstaLoop, "A_INSTALOOP"}, + {A_Custom3DRotate, "A_CUSTOM3DROTATE"}, + {A_SearchForPlayers, "A_SEARCHFORPLAYERS"}, + {A_CheckRandom, "A_CHECKRANDOM"}, + {A_CheckTargetRings, "A_CHECKTARGETRINGS"}, + {A_CheckRings, "A_CHECKRINGS"}, + {A_CheckTotalRings, "A_CHECKTOTALRINGS"}, + {A_CheckHealth, "A_CHECKHEALTH"}, + {A_CheckRange, "A_CHECKRANGE"}, + {A_CheckHeight, "A_CHECKHEIGHT"}, + {A_CheckTrueRange, "A_CHECKTRUERANGE"}, + {A_CheckThingCount, "A_CHECKTHINGCOUNT"}, + {A_CheckAmbush, "A_CHECKAMBUSH"}, + {A_CheckCustomValue, "A_CHECKCUSTOMVALUE"}, + {A_CheckCusValMemo, "A_CHECKCUSVALMEMO"}, + {A_SetCustomValue, "A_SETCUSTOMVALUE"}, + {A_UseCusValMemo, "A_USECUSVALMEMO"}, + {A_RelayCustomValue, "A_RELAYCUSTOMVALUE"}, + {A_CusValAction, "A_CUSVALACTION"}, + {A_ForceStop, "A_FORCESTOP"}, + {A_ForceWin, "A_FORCEWIN"}, + {A_SpikeRetract, "A_SPIKERETRACT"}, + {A_InfoState, "A_INFOSTATE"}, + {A_Repeat, "A_REPEAT"}, + {A_SetScale, "A_SETSCALE"}, + {A_RemoteDamage, "A_REMOTEDAMAGE"}, + {A_HomingChase, "A_HOMINGCHASE"}, + {A_TrapShot, "A_TRAPSHOT"}, + {A_VileTarget, "A_VILETARGET"}, + {A_VileAttack, "A_VILEATTACK"}, + {A_VileFire, "A_VILEFIRE"}, + {A_BrakChase, "A_BRAKCHASE"}, + {A_BrakFireShot, "A_BRAKFIRESHOT"}, + {A_BrakLobShot, "A_BRAKLOBSHOT"}, + {A_NapalmScatter, "A_NAPALMSCATTER"}, + {A_SpawnFreshCopy, "A_SPAWNFRESHCOPY"}, + //{A_InvincSparkleRotate, "A_INVINCSPARKLEROTATE"}, - {{NULL}, "NONE"}, + {NULL, "NONE"}, // This NULL entry must be the last in the list - {{NULL}, NULL}, + {NULL, NULL}, }; static void readframe(MYFILE *f, INT32 num) @@ -1702,7 +1703,7 @@ static void readframe(MYFILE *f, INT32 num) for (z = 0; actionpointers[z].name; z++) { - if (actionpointers[z].action.acv == states[num].action.acv) + if (actionpointers[z].action == states[num].action) { break; } @@ -1711,17 +1712,17 @@ static void readframe(MYFILE *f, INT32 num) z = 0; found = LUA_SetLuaAction(&states[num], actiontocompare); if (!found) - while (actionpointers[z].name) { - if (fastcmp(actiontocompare, actionpointers[z].name)) + while (actionpointers[z].name) { - states[num].action = actionpointers[z].action; - states[num].action.acv = actionpointers[z].action.acv; // assign - states[num].action.acp1 = actionpointers[z].action.acp1; - found = true; - break; + if (fastcmp(actiontocompare, actionpointers[z].name)) + { + states[num].action = actionpointers[z].action; + found = true; + break; + } + z++; } - z++; } if (!found) @@ -8524,13 +8525,13 @@ static inline int lib_freeslot(lua_State *L) // Arguments: mobj_t actor, int var1, int var2 static inline int lib_action(lua_State *L) { - actionf_t *action = lua_touserdata(L,lua_upvalueindex(1)); + actionf_p1 *action = lua_touserdata(L,lua_upvalueindex(1)); mobj_t *actor = *((mobj_t **)luaL_checkudata(L,1,META_MOBJ)); var1 = (INT32)luaL_optinteger(L,2,0); var2 = (INT32)luaL_optinteger(L,3,0); if (!actor) return LUA_ErrInvalid(L, "mobj_t"); - action->acp1(actor); + (*action)(actor); return 0; } @@ -9344,13 +9345,15 @@ int LUA_SOCLib(lua_State *L) const char *LUA_GetActionName(void *action) { - actionf_t *act = (actionf_t *)action; + actionf_p1 *act = (actionf_p1 *)action; size_t z; + for (z = 0; actionpointers[z].name; z++) { - if (actionpointers[z].action.acv == act->acv) + if (actionpointers[z].action == *act) return actionpointers[z].name; } + return NULL; } @@ -9363,8 +9366,6 @@ void LUA_SetActionByName(void *state, const char *actiontocompare) if (fasticmp(actiontocompare, actionpointers[z].name)) { st->action = actionpointers[z].action; - st->action.acv = actionpointers[z].action.acv; // assign - st->action.acp1 = actionpointers[z].action.acp1; return; } } diff --git a/src/discord.c b/src/discord.c index cd7dafa8f..158c79f7f 100644 --- a/src/discord.c +++ b/src/discord.c @@ -489,7 +489,7 @@ void DRPC_UpdatePresence(void) { #endif discordPresence.state = "Private"; -#ifdef MASTERSERVER +#ifdef MASTERSERVER } #endif diff --git a/src/doomtype.h b/src/doomtype.h index 174bba5b1..a7387b850 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -17,6 +17,8 @@ #ifndef __DOOMTYPE__ #define __DOOMTYPE__ +#include "stdbool.h" + #if defined (_WIN32) //#define WIN32_LEAN_AND_MEAN #define RPC_NO_WINDOWS_H @@ -155,23 +157,11 @@ size_t strlcpy(char *dst, const char *src, size_t siz); #define STRBUFCPY(dst,src) strlcpy(dst, src, sizeof dst) /* Boolean type definition */ - -// \note __BYTEBOOL__ used to be set above if "macintosh" was defined, -// if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now? -#ifndef __BYTEBOOL__ - #define __BYTEBOOL__ - - //faB: clean that up !! - #if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward - #include "stdbool.h" - #elif defined (_WIN32) - #define false FALSE // use windows types - #define true TRUE - #define boolean BOOL - #else - typedef enum {false, true} boolean; - #endif -#endif // __BYTEBOOL__ +#ifdef _WIN32 +#define boolean bool +#else +typedef bool boolean; +#endif /* 7.18.2.1 Limits of exact-width integer types */ #ifndef INT8_MIN diff --git a/src/g_game.c b/src/g_game.c index 200ce7834..25e21438f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2629,7 +2629,7 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) // scan all thinkers for (th = thinkercap.next; th != &thinkercap; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) + if (th->function != (actionf_p1)P_MobjThinker) continue; mo2 = (mobj_t *)th; @@ -5213,7 +5213,7 @@ void G_ConsGhostTic(INT32 playernum) mobj = NULL; for (th = thinkercap.next; th != &thinkercap; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) + if (th->function != (actionf_p1)P_MobjThinker) continue; mobj = (mobj_t *)th; if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z) @@ -6130,38 +6130,39 @@ void G_BeginRecording(void) CV_SaveNetVars(&demobuf.p, true); // Now store some info for each in-game player - for (p = 0; p < MAXPLAYERS; p++) { - if (playeringame[p]) { - player = &players[p]; + for (p = 0; p < MAXPLAYERS; p++) + { + if (!playeringame[p]) + continue; - WRITEUINT8(demobuf.p, p | (player->spectator ? DEMO_SPECTATOR : 0)); + player = &players[p]; - // Name - memset(name, 0, 16); - memcpy(name, player_names[p], 15); - M_Memcpy(demobuf.p,name,16); - demobuf.p += 16; + WRITEUINT8(demobuf.p, p | (player->spectator ? DEMO_SPECTATOR : 0)); - // Skin - memset(name, 0, 16); - strncpy(name, skins[player->skin].name, 16); - M_Memcpy(demobuf.p,name,16); - demobuf.p += 16; + // Name + memset(name, 0, 16); + memcpy(name, player_names[p], 15); + M_Memcpy(demobuf.p,name,16); + demobuf.p += 16; - // Color - memset(name, 0, 16); - strncpy(name, KartColor_Names[player->skincolor], 16); - M_Memcpy(demobuf.p,name,16); - demobuf.p += 16; + // Skin + memset(name, 0, 16); + strncpy(name, skins[player->skin].name, 16); + M_Memcpy(demobuf.p,name,16); + demobuf.p += 16; - // Score, since Kart uses this to determine where you start on the map - WRITEUINT32(demobuf.p, player->score); + // Color + memset(name, 0, 16); + strncpy(name, KartColor_Names[player->skincolor], 16); + M_Memcpy(demobuf.p,name,16); + demobuf.p += 16; - // Kart speed and weight - WRITEUINT8(demobuf.p, skins[player->skin].kartspeed); - WRITEUINT8(demobuf.p, skins[player->skin].kartweight); + // Score, since Kart uses this to determine where you start on the map + WRITEUINT32(demobuf.p, player->score); - } + // Kart speed and weight + WRITEUINT8(demobuf.p, skins[player->skin].kartspeed); + WRITEUINT8(demobuf.p, skins[player->skin].kartweight); } WRITEUINT8(demobuf.p, 0xFF); // Denote the end of the player listing @@ -7274,9 +7275,9 @@ void G_DoPlayDemo(char *defdemoname) //LUA_HookInt(gamemap, HOOK(MapChange)); consoleplayer = 0; - memset(playeringame,0,sizeof(playeringame)); - memset(displayplayers,0,sizeof(displayplayers)); - memset(camera,0,sizeof(camera)); // reset freecam + memset(playeringame, 0, sizeof(playeringame)); + memset(displayplayers, 0, sizeof(displayplayers)); + memset(camera, 0, sizeof(camera)); // reset freecam // Load players that were in-game when the map started p = READUINT8(demobuf.p); @@ -7852,7 +7853,7 @@ void G_DoPlayMetal(void) // find metal sonic for (th = thinkercap.next; th != &thinkercap; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) + if (th->function != (actionf_p1)P_MobjThinker) continue; mo = (mobj_t *)th; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 85e50465a..7254ba227 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -787,7 +787,7 @@ static void HWR_PrecacheLevelSprites(void) for (th = thinkercap.next; th != &thinkercap; th = th->next) { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) + if (th->function != (actionf_p1)P_MobjThinker) continue; mo = (mobj_t *)th; diff --git a/src/info.c b/src/info.c index 7afc76bf6..1d2326cec 100644 --- a/src/info.c +++ b/src/info.c @@ -78,3336 +78,3279 @@ state_t states[NUMSTATES] = // (or tr_trans10<