diff --git a/src/k_collide.c b/src/k_collide.c index 87027b20b..3b17e1f63 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -545,52 +545,42 @@ static void K_BubbleShieldCollideDrain(player_t *player, mobj_t *bubble) } } -static boolean K_BubbleReflectingTrapItem(mobjtype_t t) +static boolean K_BubbleReflectingTrapItem(const mobj_t *t) { - return ((t == MT_BANANA) || (t == MT_JAWZ_DUD) || (t == MT_SSMINE) || (t == MT_LANDMINE) || - (t == MT_EGGMANITEM) || (t == MT_SSMINE_SHIELD)); + return t->type == MT_BANANA || (t->type == MT_ORBINAUT && t->flags2 & MF2_AMBUSH) || t->type == MT_JAWZ_DUD || + t->type == MT_EGGMANITEM || t->type == MT_SSMINE || t->type == MT_SSMINE_SHIELD || t->type == MT_LANDMINE; } -boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2, boolean isplayer) +boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2) { mobj_t *owner = t1->player ? t1 : t1->target; - INT32 div = 2; - if (isplayer) + if (!t2->threshold || t2->player) { - div = 1; - } + angle_t angle = R_PointToAngle2(t1->x, t1->y, t2->x, t2->y); + fixed_t momentum = max(FixedHypot(owner->momx, owner->momy), FixedHypot(t2->momx, t2->momy)); + momentum = max(3*momentum/4, 16*mapobjectscale); // do SOMETHING! - if ((!t2->threshold)||(isplayer)) - { - if (!t2->momx && !t2->momy) + P_InstaThrust(t2, angle, momentum); + if (!t2->player) + t2->angle = angle; + + if (K_BubbleReflectingTrapItem(t2)) { + // Stupid hack: Toss trap/dud items into the air t2->momz += (24*t2->scale) * P_MobjFlip(t2); - } - else - { - t2->momx = (-1*t2->momx)/div; - t2->momy = (-1*t2->momy)/div; - t2->momz = (-1*t2->momz)/div; - - if (!isplayer) - { - t2->angle += ANGLE_180; - } - - if (K_BubbleReflectingTrapItem(t2->type)) - { - // Stupid hack: Toss trap/dud items into the air - t2->momz += (24*t2->scale) * P_MobjFlip(t2); - } + t2->z += t2->momz; } - if (!isplayer) + if (!t2->player) { if (t2->type == MT_JAWZ) P_SetTarget(&t2->tracer, t2->target); // Back to the source! P_SetTarget(&t2->target, owner); // Let the source reflect it back again! - t2->threshold = 10; + if ((t2->type == MT_ORBINAUT && t2->flags2 & MF2_AMBUSH) || t2->type == MT_JAWZ_DUD) + t2->flags |= MF_NOCLIPTHING; + else + t2->threshold = 10; } S_StartSound(t1, sfx_s3k44); } @@ -633,7 +623,7 @@ boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2) // Drain my stuff please. K_BubbleShieldCollideDrain(t1->target->player, t1); } - return K_BubbleShieldReflect(t1, t2, (t2->player) ? true : false); + return K_BubbleShieldReflect(t1, t2); } if (t2->flags & MF_SHOOTABLE) diff --git a/src/k_collide.h b/src/k_collide.h index 2e0264ebe..2677f409b 100644 --- a/src/k_collide.h +++ b/src/k_collide.h @@ -17,7 +17,7 @@ boolean K_MineExplosionCollide(mobj_t *t1, mobj_t *t2); boolean K_LandMineCollide(mobj_t *t1, mobj_t *t2); void K_ThunderShieldAttack(mobj_t *actor, fixed_t size); -boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2, boolean isplayer); +boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2); boolean K_BubbleShieldCanReflect(mobj_t *t1, mobj_t *t2); boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2); diff --git a/src/p_map.c b/src/p_map.c index 5a36345c2..9d17208e4 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -675,30 +675,6 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) return K_SMKIceBlockCollide(thing, g_tm.thing) ? BMIT_CONTINUE : BMIT_ABORT; } - if (g_tm.thing->type == MT_EGGMANITEM || g_tm.thing->type == MT_EGGMANITEM_SHIELD) - { - // see if it went over / under - if (g_tm.thing->z > thing->z + thing->height) - return BMIT_CONTINUE; // overhead - if (g_tm.thing->z + g_tm.thing->height < thing->z) - return BMIT_CONTINUE; // underneath - - return K_EggItemCollide(g_tm.thing, thing) ? BMIT_CONTINUE : BMIT_ABORT; - } - else if (thing->type == MT_EGGMANITEM || thing->type == MT_EGGMANITEM_SHIELD) - { - // see if it went over / under - if (g_tm.thing->z > thing->z + thing->height) - return BMIT_CONTINUE; // overhead - if (g_tm.thing->z + g_tm.thing->height < thing->z) - return BMIT_CONTINUE; // underneath - - return K_EggItemCollide(thing, g_tm.thing) ? BMIT_CONTINUE : BMIT_ABORT; - } - - if (g_tm.thing->type == MT_RANDOMITEM) - return BMIT_CONTINUE; - // Bubble Shield reflect if (thing->type == MT_BUBBLESHIELD && !P_MobjWasRemoved(thing->target) && thing->target->player && thing->target->player->bubbleblowup) { @@ -725,6 +701,30 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) if (thing->type == MT_BUBBLESHIELD || g_tm.thing->type == MT_BUBBLESHIELD) return BMIT_CONTINUE; + if (g_tm.thing->type == MT_EGGMANITEM || g_tm.thing->type == MT_EGGMANITEM_SHIELD) + { + // see if it went over / under + if (g_tm.thing->z > thing->z + thing->height) + return BMIT_CONTINUE; // overhead + if (g_tm.thing->z + g_tm.thing->height < thing->z) + return BMIT_CONTINUE; // underneath + + return K_EggItemCollide(g_tm.thing, thing) ? BMIT_CONTINUE : BMIT_ABORT; + } + else if (thing->type == MT_EGGMANITEM || thing->type == MT_EGGMANITEM_SHIELD) + { + // see if it went over / under + if (g_tm.thing->z > thing->z + thing->height) + return BMIT_CONTINUE; // overhead + if (g_tm.thing->z + g_tm.thing->height < thing->z) + return BMIT_CONTINUE; // underneath + + return K_EggItemCollide(thing, g_tm.thing) ? BMIT_CONTINUE : BMIT_ABORT; + } + + if (g_tm.thing->type == MT_RANDOMITEM) + return BMIT_CONTINUE; + if (g_tm.thing->type == MT_ORBINAUT || g_tm.thing->type == MT_JAWZ || g_tm.thing->type == MT_JAWZ_DUD || g_tm.thing->type == MT_ORBINAUT_SHIELD || g_tm.thing->type == MT_JAWZ_SHIELD) { diff --git a/src/p_mobj.c b/src/p_mobj.c index b5541bc3a..644bf1d9a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9356,7 +9356,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->slopepitch = 0; mobj->sloperoll = 0; + mobj->flags &= ~(MF_NOCLIP|MF_NOCLIPTHING); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + mobj->flags |= MF_NOCLIP|MF_NOCLIPTHING; break; } case MT_BUBBLESHLD_DEBRIS: @@ -9380,7 +9382,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (curstate != S_INVISIBLE) { // "Despawn" and play the glass landing sound. - S_StartSound(mobj, mobj->info->activesound); + S_StartSoundAtVolume(mobj, mobj->info->activesound, 40); P_SetMobjState(mobj, S_INVISIBLE); } }