diff --git a/src/info.c b/src/info.c index 5d82fe06e..3b99615d3 100644 --- a/src/info.c +++ b/src/info.c @@ -12860,10 +12860,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 8, // reactiontime (sets number of frames the rock cycles through) sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + 12*TICRATE, // painchance (sets how long an unridden rock should last before disappearing - set to 0 to disable) sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate diff --git a/src/p_enemy.c b/src/p_enemy.c index 6fdb68ac4..20b9f9b03 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13935,7 +13935,7 @@ void A_RolloutSpawn(mobj_t *actor) || P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1) { actor->target = P_SpawnMobj(actor->x, actor->y, actor->z, locvar2); - actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)); + actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)) | MF2_SLIDEPUSH; actor->target->eflags |= (actor->eflags & MFE_VERTICALFLIP); } } @@ -13957,41 +13957,45 @@ void A_RolloutRock(mobj_t *actor) return; #endif - UINT8 maxframes = actor->info->reactiontime; + UINT8 maxframes = actor->info->reactiontime; // number of frames the mobj cycles through fixed_t pi = (22*FRACUNIT/7); - fixed_t circumference = FixedMul(2 * pi, actor->radius); + fixed_t circumference = FixedMul(2 * pi, actor->radius); // used to calculate when to change frame fixed_t speed = P_AproxDistance(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale); boolean inwater = actor->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER); - actor->friction = FRACUNIT; + actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves - if (inwater && !(actor->flags2 & MF2_AMBUSH)) + if (inwater && !(actor->flags2 & MF2_AMBUSH)) // buoyancy in water (or lava) { actor->momz = FixedMul(actor->momz, locvar2); actor->momz += P_MobjFlip(actor) * FixedMul(locvar2, actor->scale); } - if (speed > topspeed) + if (speed > topspeed) // cap speed { actor->momx = FixedMul(FixedDiv(actor->momx, speed), topspeed); actor->momy = FixedMul(FixedDiv(actor->momy, speed), topspeed); } + + if (P_IsObjectOnGround(actor) || inwater) // apply drag to speed (compensates for lack of friction but also works in liquids) + { + actor->momx = FixedMul(actor->momx, locvar1); + actor->momy = FixedMul(actor->momy, locvar1); + } - actor->momx = FixedMul(actor->momx, locvar1); - actor->momy = FixedMul(actor->momy, locvar1); + speed = P_AproxDistance(actor->momx, actor->momy); // recalculate speed for visual rolling - speed = P_AproxDistance(actor->momx, actor->momy); - - if (speed < actor->scale >> 1) + if (speed < actor->scale >> 1) // stop moving if speed is insignificant { actor->momx = 0; actor->momy = 0; } else if (speed > actor->scale) { - actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); + actor->movecount = 1; // rock has moved; fuse should be set so we don't have a trillion rocks lying around + actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); // set rock's angle to movement direction actor->movefactor += speed; - if (actor->movefactor > circumference / maxframes) + if (actor->movefactor > circumference / maxframes) // if distance moved is enough to change frame, change it! { actor->reactiontime++; actor->reactiontime %= maxframes; @@ -13999,5 +14003,14 @@ void A_RolloutRock(mobj_t *actor) } } - actor->frame = actor->reactiontime % maxframes; + actor->frame = actor->reactiontime % maxframes; // set frame + + if (!(actor->flags & MF_PUSHABLE)) // if being ridden, don't disappear + actor->fuse = 0; + else if (!actor->fuse && actor->movecount == 1) // otherwise if rock has moved, set its fuse + actor->fuse = actor->info->painchance; + + if (actor->fuse && actor->fuse < 2*TICRATE) + actor->flags2 ^= MF2_DONTDRAW; + } diff --git a/src/p_map.c b/src/p_map.c index b62e33372..e470de240 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -978,6 +978,7 @@ static boolean PIT_CheckThing(mobj_t *thing) || (tmthing->eflags & MFE_VERTICALFLIP && abs(tmthing->z + tmthing->height - thing->z) < (thing->height>>2)))) { thing->flags &= ~MF_PUSHABLE; // prevent riding player from applying pushable movement logic + thing->flags2 &= ~MF2_DONTDRAW; // don't leave the rock invisible if it was flashing prior to boarding P_SetTarget(&thing->tracer, tmthing); P_ResetPlayer(tmthing->player); P_SetPlayerMobjState(tmthing, S_PLAY_WALK);