diff --git a/src/p_inter.c b/src/p_inter.c index a94daafab..45fd9180c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -826,6 +826,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; } + if (special->extravalue1) + { + // Don't get during destruction + return; + } + if ( grandprixinfo.gp == true // Bonus Round && netgame == false // game design + makes it easier to implement @@ -833,13 +839,30 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) ) { gamedata->thisprisoneggpickupgrabbed = true; - gamedata->prisoneggstothispickup = GDINIT_PRISONSTOPRIZE; + if (gamedata->prisoneggstothispickup < GDINIT_PRISONSTOPRIZE) + { + // Just in case it's set absurdly low for testing. + gamedata->prisoneggstothispickup = GDINIT_PRISONSTOPRIZE; + } if (!M_UpdateUnlockablesAndExtraEmblems(true, true)) S_StartSound(NULL, sfx_ncitem); gamedata->deferredsave = true; } + statenum_t teststate = (special->state-states); + + if (teststate == S_PRISONEGGDROP_CD) + { + special->momz = P_MobjFlip(special) * 2 * mapobjectscale; + special->flags = (special->flags & ~MF_SPECIAL) | (MF_NOGRAVITY|MF_NOCLIPHEIGHT); + special->extravalue1 = 1; + + special->renderflags = (special->renderflags & ~RF_BRIGHTMASK) | (RF_ADD | RF_FULLBRIGHT); + + return; + } + break; } @@ -1011,10 +1034,7 @@ static void P_AddBrokenPrison(mobj_t *target, mobj_t *source) mobj_t *secretpickup = P_SpawnMobj( target->x, target->y, - target->z + ( - target->height - - FixedMul(mobjinfo[MT_PRISONEGGDROP].height, mapobjectscale) - ), + target->z + target->height/2, MT_PRISONEGGDROP ); diff --git a/src/p_mobj.c b/src/p_mobj.c index 3c6cbffa7..89f6fa7c5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7656,7 +7656,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->flags2 & MF2_AMBUSH) { - if (P_IsObjectOnGround(mobj)) + if (mobj->extravalue1 == 0 && P_IsObjectOnGround(mobj)) { if (P_CheckDeathPitCollide(mobj)) { @@ -7665,6 +7665,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } mobj->momx = mobj->momy = 0; + mobj->flags2 |= MF2_STRONGBOX; } teststate = (mobj->state-states); @@ -7674,6 +7675,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (gamedata->thisprisoneggpickup_cached->type == UC_PRISONEGGCD) { teststate = S_PRISONEGGDROP_CD; + mobj->renderflags |= RF_SEMIBRIGHT; } P_SetMobjState(mobj, teststate); @@ -7691,7 +7693,43 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (teststate == S_PRISONEGGDROP_CD) { - mobj->angle += ANGLE_MAX/TICRATE; + if (mobj->extravalue1) + { + ++mobj->extravalue1; + + INT32 trans = (mobj->extravalue1 * NUMTRANSMAPS) / (TICRATE); + if (trans >= NUMTRANSMAPS) + { + P_RemoveMobj(mobj); + return false; + } + + mobj->angle += ANGLE_MAX/(TICRATE/3); + mobj->renderflags = (mobj->renderflags & ~RF_TRANSMASK) | (trans << RF_TRANSSHIFT); + } + else + { + if (mobj->flags2 & MF2_STRONGBOX) + mobj->angle += ANGLE_MAX/TICRATE; + else + mobj->angle += ANGLE_MAX/(TICRATE/3); + + // Non-RNG-advancing equivalent of Obj_SpawnEmeraldSparks + if (leveltime % 3 == 0) + { + mobj_t *sparkle = P_SpawnMobjFromMobj( + mobj, + M_RandomRange(-48, 48) * FRACUNIT, + M_RandomRange(-48, 48) * FRACUNIT, + M_RandomRange(0, 64) * FRACUNIT, + MT_SPARK + ); + P_SetMobjState(sparkle, mobjinfo[MT_EMERALDSPARK].spawnstate); + + sparkle->color = M_RandomChance(FRACUNIT/2) ? SKINCOLOR_ULTRAMARINE : SKINCOLOR_MAGENTA; + sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj); + } + } } break;