diff --git a/src/k_terrain.c b/src/k_terrain.c index 1b1df12f1..92ca53df0 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -554,6 +554,61 @@ void K_ProcessTerrainEffect(mobj_t *mo) } } + // Spring + if (terrain->springStrength) + { + const pslope_t *slope; + angle_t angle = 0; + + fixed_t co = FRACUNIT; + fixed_t si = 0; + + // FIXME: come up with a better way to get the touched + // texture's slope to this function. At least this + // will work for 90% of scenarios... + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if (player->mo->ceilingrover != NULL) + { + slope = *player->mo->ceilingrover->b_slope; + } + else + { + slope = player->mo->subsector->sector->c_slope; + } + } + else + { + if (player->mo->floorrover != NULL) + { + slope = *player->mo->ceilingrover->t_slope; + } + else + { + slope = player->mo->subsector->sector->f_slope; + } + } + + if (slope) + { + const angle_t fa = (slope->zangle >> ANGLETOFINESHIFT); + + co = FINECOSINE(fa) * P_MobjFlip(player->mo); + si = -(FINESINE(fa)); + + angle = slope->xydirection; + } + + P_DoSpringEx(player->mo, mapobjectscale, + FixedMul(terrain->springStrength, co), + FixedMul(terrain->springStrength, si), + angle, terrain->springStarColor); + + // FIXME: this sound shouldn't move with the player + S_StartSound(player->mo, sfx_s3kb1); + } + // Bumpy floor if (terrain->flags & TRF_STAIRJANK) { @@ -1487,6 +1542,8 @@ static void K_TerrainDefaults(terrain_t *terrain) terrain->trickPanel = 0; terrain->speedPad = 0; terrain->speedPadAngle = 0; + terrain->springStrength = 0; + terrain->springStarColor = SKINCOLOR_NONE; terrain->flags = 0; } @@ -1565,6 +1622,27 @@ static void K_ParseTerrainParameter(size_t i, char *param, char *val) { terrain->speedPadAngle = FixedAngle(FLOAT_TO_FIXED(atof(val))); } + else if (stricmp(param, "springStrength") == 0) + { + const double fval = atof(val); + + if (fpclassify(fval) == FP_ZERO) + { + terrain->springStrength = 0; + } + else + { + // Springs increase in stength by 1.6 times the + // previous strength. Grey spring is 25 and + // 25/1.6 = 15.625 + terrain->springStrength = + FLOAT_TO_FIXED(15.625 * pow(1.6, fval)); + } + } + else if (stricmp(param, "springStarColor") == 0) + { + terrain->springStarColor = get_number(val); + } else if (stricmp(param, "floorClip") == 0) { terrain->floorClip = FLOAT_TO_FIXED(atof(val)); diff --git a/src/k_terrain.h b/src/k_terrain.h index 349455bed..166900036 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -116,6 +116,8 @@ struct terrain_t fixed_t trickPanel; // Trick panel strength fixed_t speedPad; // Speed pad strength angle_t speedPadAngle; // Speed pad angle + fixed_t springStrength; // Spring strength + UINT16 springStarColor; // Spring star color fixed_t floorClip; // Offset for sprites on this ground UINT32 flags; // Flag values (see: terrain_flags_t) }; diff --git a/src/p_map.c b/src/p_map.c index 8f6388452..a581d4576 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -277,6 +277,12 @@ P_DoSpringEx angle_t finalAngle, UINT16 starcolor) { + if (horizspeed < 0) + { + horizspeed = -(horizspeed); + finalAngle += ANGLE_180; + } + object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you. object->terrain = NULL;