Merge branch 'master' into profiles

This commit is contained in:
Sally Coolatta 2021-11-29 10:32:14 -05:00
commit c66e85700b
34 changed files with 686 additions and 197 deletions

View file

@ -198,6 +198,13 @@ typedef enum
#undef KSPIN_TYPE
} kartspinoutflags_t;
typedef enum
{
TRIP_NONE,
TRIP_PASSED,
TRIP_BLOCKED,
} tripwirestate_t;
typedef enum
{
// Unsynced, HUD or clientsided effects
@ -390,7 +397,7 @@ typedef struct player_s
fixed_t offroad; // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed
UINT8 waterskip; // Water skipping counter
UINT16 tiregrease; // Reduced friction timer after hitting a horizontal spring
UINT16 tiregrease; // Reduced friction timer after hitting a spring
UINT16 springstars; // Spawn stars around a player when they hit a spring
UINT16 springcolor; // Color of spring stars
UINT8 dashpadcooldown; // Separate the vanilla SA-style dash pads from using flashing
@ -456,9 +463,6 @@ typedef struct player_s
UINT8 trickpanel; // Trick panel state
UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold
fixed_t trickmomx;
fixed_t trickmomy;
fixed_t trickmomz;
fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks.
UINT8 trickboostdecay; // used to know how long you've waited
UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god.
@ -468,10 +472,13 @@ typedef struct player_s
UINT8 emeralds;
UINT8 bumpers;
INT16 karmadelay;
tic_t overtimekarma; // time to live in overtime comeback
INT16 spheres;
SINT8 glanceDir; // Direction the player is trying to look backwards in
UINT8 tripWireState; // see tripwirestate_t
//
SINT8 lives;

View file

@ -2288,6 +2288,10 @@ void readsound(MYFILE *f, INT32 num)
{
S_sfx[num].pitch = value;
}
else if (fastcmp(word, "VOLUME"))
{
S_sfx[num].volume = value;
}
else if (fastcmp(word, "CAPTION") || fastcmp(word, "DESCRIPTION"))
{
deh_strlcpy(S_sfx[num].caption, word2,

View file

@ -6749,6 +6749,7 @@ struct int_const_s const INT_CONST[] = {
{"TC_RAINBOW",TC_RAINBOW},
{"TC_BLINK",TC_BLINK},
{"TC_DASHMODE",TC_DASHMODE},
{"TC_HITLAG",TC_HITLAG},
// marathonmode flags
{"MA_INIT",MA_INIT},

View file

@ -2146,11 +2146,13 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->growshrinktimer = growshrinktimer;
p->bumpers = bumper;
p->karmadelay = comebacktime;
p->overtimekarma = 0;
p->eggmanblame = -1;
p->lastdraft = -1;
p->karthud[khud_fault] = khudfault;
p->nocontrol = nocontrol;
p->kickstartaccel = kickstartaccel;
p->tripWireState = TRIP_NONE;
memcpy(&p->respawn, &respawn, sizeof (p->respawn));

View file

@ -1478,7 +1478,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
transnum_t transtable = R_GetLinedefTransTable(gl_linedef);
if (transtable == NUMTRANSMAPS)
transtable = 0;
if (gl_linedef->special == 910)
if (gl_linedef->special == 910 ||
P_IsLineTripWire(gl_linedef))
blend = AST_ADD;
else if (gl_linedef->special == 911)
blend = AST_SUBTRACT;
@ -3643,7 +3644,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
pslope_t *groundslope;
// hitlag vibrating
if (thing->hitlag > 0)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
@ -5062,7 +5063,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
return;
// hitlag vibrating
if (thing->hitlag > 0)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
@ -5401,7 +5402,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->mobj = thing;
//Hurdler: 25/04/2000: now support colormap in hardware mode
if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
if (vis->mobj->hitlag > 0 && (vis->mobj->eflags & MFE_DAMAGEHITLAG))
{
vis->colormap = R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE);
}
else if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
{
if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized)
vis->colormap = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);

View file

@ -819,7 +819,12 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
while (size--)
{
if (skinnum == TC_BOSS)
if (skinnum == TC_HITLAG)
{
cur->s.red = cur->s.green = cur->s.blue = K_HitlagColorValue(*image);
cur->s.alpha = image->s.alpha;
}
else if (skinnum == TC_BOSS)
{
// Turn everything below a certain threshold white
if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127)
@ -1367,7 +1372,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
float finalscale;
// hitlag vibrating
if (spr->mobj->hitlag > 0)
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = spr->mobj->hitlag * (FRACUNIT / 10);
@ -1486,7 +1491,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
{
INT32 skinnum = TC_DEFAULT;
if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
{
skinnum = TC_HITLAG;
}
else if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
{
if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized)
skinnum = TC_ALLWHITE;

View file

@ -8686,7 +8686,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
20*FRACUNIT, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY, // flags
MF_SPECIAL|MF_NOGRAVITY, // flags
S_BALLOONPOP1 // raisestate
},

View file

@ -179,7 +179,7 @@ mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT
P_Thrust(emerald,
FixedAngle(P_RandomFixed() * 180) + angle,
32 * mapobjectscale);
24 * mapobjectscale);
emerald->momz = flip * 24 * mapobjectscale;
if (emerald->eflags & MFE_UNDERWATER)
@ -288,12 +288,6 @@ void K_RunPaperItemSpawners(void)
if (overtime == true)
{
if (battleovertime.radius < 512*mapobjectscale)
{
// Barrier has closed in too much
return;
}
// Double frequency of items
interval /= 2;
}
@ -557,10 +551,12 @@ void K_RunBattleOvertime(void)
}
else if (battleovertime.radius > 0)
{
if (battleovertime.radius > 2*mapobjectscale)
const fixed_t minradius = 768 * mapobjectscale;
if (battleovertime.radius > minradius)
battleovertime.radius -= 2*mapobjectscale;
else
battleovertime.radius = 0;
battleovertime.radius = minradius;
}
if (battleovertime.radius > 0)

View file

@ -90,6 +90,59 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor)
}
}
/*--------------------------------------------------
UINT8 K_HitlagColorValue(RGBA_t color)
See header file for description.
--------------------------------------------------*/
UINT8 K_HitlagColorValue(RGBA_t color)
{
// Outputs a raw brightness value (makes OGL support easier)
INT32 output = K_ColorRelativeLuminance(color.s.red, color.s.green, color.s.blue);
// Invert the color
output = 255 - output;
// Increase the contrast
output = ((output-128) * 2) + 128;
// Make sure to cap it.
if (output > 255)
{
output = 255;
}
else if (output < 0)
{
output = 0;
}
return output;
}
/*--------------------------------------------------
void K_HitlagColormap(UINT8 *dest_colormap)
See header file for description.
--------------------------------------------------*/
void K_HitlagColormap(UINT8 *dest_colormap)
{
RGBA_t color;
UINT8 v, offset;
INT32 i;
// for every colour in the palette, invert, greyscale, and increase the contrast.
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
{
color = V_GetColor(i);
v = K_HitlagColorValue(color);
// Convert raw brightness value to an offset from the greyscale palette line
offset = (255 - v) / 8;
dest_colormap[i] = offset; // Starts from 0, add it if greyscale moves.
}
}
/*--------------------------------------------------
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color)
@ -100,13 +153,18 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color)
INT32 i;
INT32 starttranscolor;
// Handle a couple of simple special cases
if (skinnum == TC_BOSS
if (skinnum == TC_HITLAG)
{
K_HitlagColormap(dest_colormap);
return;
}
else if (skinnum == TC_BOSS
|| skinnum == TC_ALLWHITE
|| skinnum == TC_METALSONIC
|| skinnum == TC_BLINK
|| color == SKINCOLOR_NONE)
{
// Handle a couple of simple special cases
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
{
if (skinnum == TC_ALLWHITE)

View file

@ -66,6 +66,35 @@ UINT16 K_RainbowColor(tic_t time);
void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
/*--------------------------------------------------
UINT8 K_HitlagColorValue(RGBA_t color);
Gets the new replacement brightness value for the hitlag effect.
Input Arguments:-
color - Input color we intend to replace.
Return:-
0 to 255 brightness value.
--------------------------------------------------*/
UINT8 K_HitlagColorValue(RGBA_t color);
/*--------------------------------------------------
void K_HitlagColormap(UINT8 *dest_colormap);
Generates a inverted hi-contrast greyscale colormap,
for the hitlag effect.
Input Arguments:-
dest_colormap - Colormap to populate.
Return:-
None
--------------------------------------------------*/
void K_HitlagColormap(UINT8 *dest_colormap);
/*--------------------------------------------------
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color);

View file

@ -2460,7 +2460,8 @@ static void K_drawKartBumpersOrKarma(void)
else
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap);
V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->bumpers, maxbumper));
// TODO BETTER HUD
V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d %d", stplyr->bumpers, maxbumper, stplyr->overtimekarma / TICRATE));
}
}
}
@ -3742,7 +3743,7 @@ static void K_drawKartFirstPerson(void)
fixed_t yoffs = -P_ReturnThrustX(stplyr->mo, ang, 4*FRACUNIT);
// hitlag vibrating
if (stplyr->mo->hitlag > 0)
if (stplyr->mo->hitlag > 0 && (stplyr->mo->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = stplyr->mo->hitlag * (FRACUNIT / 10);
if (r_splitscreen && mul > FRACUNIT)

View file

@ -2673,6 +2673,19 @@ boolean K_SlopeResistance(player_t *player)
return false;
}
boolean K_TripwirePass(player_t *player)
{
if (
player->invincibilitytimer ||
player->sneakertimer ||
player->growshrinktimer > 0 ||
player->flamedash ||
player->speed > 2 * K_GetKartSpeed(player, false)
)
return true;
return false;
}
static fixed_t K_FlameShieldDashVar(INT32 val)
{
// 1 second = 75% + 50% top speed
@ -3021,74 +3034,66 @@ angle_t K_MomentumAngle(mobj_t *mo)
}
}
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics)
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage)
{
boolean mo1valid = (mo1 && !P_MobjWasRemoved(mo1));
boolean mo2valid = (mo2 && !P_MobjWasRemoved(mo2));
if (mo == NULL || P_MobjWasRemoved(mo))
{
return;
}
INT32 tics1 = tics;
INT32 tics2 = tics;
mo->hitlag += tics;
mo->hitlag = min(mo->hitlag, MAXHITLAGTICS);
if (fromDamage == true)
{
// Dunno if this should flat-out &~ the flag out too.
// Decided it probably just just keep it since it's "adding" hitlag.
mo->eflags |= MFE_DAMAGEHITLAG;
}
}
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage)
{
INT32 finalTics = tics;
if (tics <= 0)
{
return;
}
if (mo1valid == true && mo2valid == true)
if ((mo1 && !P_MobjWasRemoved(mo1)) == true && (mo2 && !P_MobjWasRemoved(mo2)) == true)
{
const INT32 mintics = tics;
const fixed_t ticaddfactor = mapobjectscale * 8;
const fixed_t speedTicFactor = (mapobjectscale * 8);
const INT32 angleTicFactor = ANGLE_22h;
const fixed_t mo1speed = FixedHypot(FixedHypot(mo1->momx, mo1->momy), mo1->momz);
const fixed_t mo2speed = FixedHypot(FixedHypot(mo2->momx, mo2->momy), mo2->momz);
const fixed_t speeddiff = mo2speed - mo1speed;
const fixed_t speedDiff = abs(mo2speed - mo1speed);
const fixed_t scalediff = mo2->scale - mo1->scale;
const fixed_t scaleDiff = abs(mo2->scale - mo1->scale);
const angle_t mo1angle = K_MomentumAngle(mo1);
const angle_t mo2angle = K_MomentumAngle(mo2);
angle_t mo1angle = K_MomentumAngle(mo1);
angle_t mo2angle = K_MomentumAngle(mo2);
INT32 angleDiff = 0;
angle_t anglediff = mo1angle - mo2angle;
fixed_t anglemul = FRACUNIT;
if (anglediff > ANGLE_180)
if (mo1speed > 0 && mo2speed > 0)
{
anglediff = InvAngle(anglediff);
// If either object is completely not moving, their speed doesn't matter.
angleDiff = AngleDelta(mo1angle, mo2angle);
}
anglemul = FRACUNIT + (AngleFixed(anglediff) / 180); // x1.0 at 0, x1.5 at 90, x2.0 at 180
// Add extra "damage" based on what was happening to the objects on impact.
finalTics += (FixedMul(speedDiff, FRACUNIT + scaleDiff) / speedTicFactor) + (angleDiff / angleTicFactor);
/*
CONS_Printf("anglemul: %f\n", FIXED_TO_FLOAT(anglemul));
CONS_Printf("speeddiff: %f\n", FIXED_TO_FLOAT(speeddiff));
CONS_Printf("scalediff: %f\n", FIXED_TO_FLOAT(scalediff));
*/
tics1 += FixedMul(speeddiff, FixedMul(anglemul, FRACUNIT + scalediff)) / ticaddfactor;
tics2 += FixedMul(-speeddiff, FixedMul(anglemul, FRACUNIT - scalediff)) / ticaddfactor;
if (tics1 < mintics)
// This shouldn't happen anymore, but just in case something funky happens.
if (finalTics < tics)
{
tics1 = mintics;
}
if (tics2 < mintics)
{
tics2 = mintics;
finalTics = tics;
}
}
//CONS_Printf("tics1: %d, tics2: %d\n", tics1, tics2);
if (mo1valid == true)
{
mo1->hitlag = max(tics1, mo1->hitlag);
}
if (mo2valid == true)
{
mo2->hitlag = max(tics2, mo2->hitlag);
}
K_AddHitLag(mo1, finalTics, fromDamage);
K_AddHitLag(mo2, finalTics, fromDamage);
}
void K_DoInstashield(player_t *player)
@ -3205,10 +3210,18 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
player->tumbleBounces = 1;
player->mo->momx = 2 * player->mo->momx / 3;
player->mo->momy = 2 * player->mo->momy / 3;
if (player->tripWireState == TRIP_PASSED)
{
player->tumbleHeight = 50;
}
else
{
player->mo->momx = 2 * player->mo->momx / 3;
player->mo->momy = 2 * player->mo->momy / 3;
player->tumbleHeight = 30;
}
player->tumbleHeight = 30;
player->pflags &= ~PF_TUMBLESOUND;
if (inflictor && !P_MobjWasRemoved(inflictor))
@ -3308,6 +3321,23 @@ static void K_HandleTumbleSound(player_t *player)
}
}
void K_ApplyTripWire(player_t *player, tripwirestate_t state)
{
if (state == TRIP_PASSED)
S_StartSound(player->mo, sfx_ssa015);
else if (state == TRIP_BLOCKED)
S_StartSound(player->mo, sfx_kc40);
player->tripWireState = state;
K_AddHitLag(player->mo, 10, false);
if (state == TRIP_PASSED && player->spinouttimer &&
player->speed > 2* K_GetKartSpeed(player, false))
{
K_TumblePlayer(player, NULL, NULL);
}
}
INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer
{
INT32 ringburst = 10;
@ -5121,7 +5151,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
thrust = FixedMul(thrust, 9*FRACUNIT/8);
}
mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = mo->player->tricktime = 0; // Reset post-hitlag momentums and timer
mo->player->tricktime = 0; // Reset post-hitlag timer
// Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25)
mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0)*125/100;
//CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT);
@ -6890,6 +6920,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
K_KartPlayerHUDUpdate(player);
if (battleovertime.enabled && !(player->pflags & PF_ELIMINATED) && player->bumpers <= 0 && player->karmadelay <= 0)
{
if (player->overtimekarma)
player->overtimekarma--;
else
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER);
}
if ((battleovertime.enabled >= 10*TICRATE) && !(player->pflags & PF_ELIMINATED))
{
fixed_t distanceToBarrier = 0;
@ -6984,11 +7022,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// Handle invincibility sfx
K_UpdateInvincibilitySounds(player); // Also thanks, VAda!
// Plays the music after the starting countdown.
if (P_IsLocalPlayer(player) && leveltime == (starttime + (TICRATE/2)))
if (player->tripWireState != TRIP_NONE)
{
S_ChangeMusic(mapmusname, mapmusflags, true);
S_ShowMusicCredit();
if (player->tripWireState == TRIP_PASSED)
S_StartSound(player->mo, sfx_cdfm63);
else if (player->tripWireState == TRIP_BLOCKED)
S_StartSound(player->mo, sfx_kc4c);
player->tripWireState = TRIP_NONE;
}
}
@ -8342,7 +8383,7 @@ void K_AdjustPlayerFriction(player_t *player)
return;
}
// Reduce friction after hitting a horizontal spring
// Reduce friction after hitting a spring
if (player->tiregrease)
{
player->mo->friction += ((FRACUNIT - prevfriction) / greasetics) * player->tiregrease;
@ -9208,29 +9249,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (cmd->turning > 0)
{
P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2));
player->trickmomx = player->mo->momx;
player->trickmomy = player->mo->momy;
player->trickmomz = player->mo->momz;
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 2;
player->mo->hitlag = TRICKLAG;
player->mo->eflags &= ~MFE_DAMAGEHITLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (cmd->turning < 0)
{
P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*5/2));
player->trickmomx = player->mo->momx;
player->trickmomy = player->mo->momy;
player->trickmomz = player->mo->momz;
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 3;
player->mo->hitlag = TRICKLAG;
player->mo->eflags &= ~MFE_DAMAGEHITLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (player->throwdir == 1)
@ -9241,15 +9274,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3));
player->trickmomx = player->mo->momx;
player->trickmomy = player->mo->momy;
player->trickmomz = player->mo->momz;
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 2;
player->mo->hitlag = TRICKLAG;
player->mo->eflags &= ~MFE_DAMAGEHITLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (player->throwdir == -1)
@ -9271,30 +9300,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
//CONS_Printf("decay: %d\n", player->trickboostdecay);
P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative);
player->trickmomx = player->mo->momx;
player->trickmomy = player->mo->momy;
player->trickmomz = player->mo->momz;
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 4;
player->mo->hitlag = TRICKLAG;
player->mo->eflags &= ~MFE_DAMAGEHITLAG;
K_trickPanelTimingVisual(player, momz);
}
}
}
// After hitlag, we will get here and will be able to apply the desired momentums!
else if (player->trickmomx || player->trickmomy || player->trickmomz)
{
player->mo->momx = player->trickmomx;
player->mo->momy = player->trickmomy;
player->mo->momz = player->trickmomz;
player->trickmomx = player->trickmomy = player->trickmomz = 0;
}
else if (player->trickpanel == 4 && P_IsObjectOnGround(player->mo)) // Upwards trick landed!
{
//CONS_Printf("apply boost\n");

View file

@ -19,6 +19,7 @@ Make sure this matches the actual number of states
*/
#define KART_NUMINVSPARKLESANIM 12
#define MAXHITLAGTICS 18 //12
player_t *K_GetItemBoxPlayer(mobj_t *mobj);
angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed);
@ -55,7 +56,8 @@ void K_KartPlayerHUDUpdate(player_t *player);
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
void K_KartPlayerAfterThink(player_t *player);
angle_t K_MomentumAngle(mobj_t *mo);
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics);
void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage);
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage);
void K_DoInstashield(player_t *player);
void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved);
void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type);
@ -103,6 +105,8 @@ void K_StripOther(player_t *player);
void K_MomentumToFacing(player_t *player);
boolean K_ApplyOffroad(player_t *player);
boolean K_SlopeResistance(player_t *player);
boolean K_TripwirePass(player_t *player);
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
INT16 K_GetSpindashChargeTime(player_t *player);
fixed_t K_GetSpindashChargeSpeed(player_t *player);
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);

View file

@ -41,6 +41,7 @@ enum sfxinfo_read {
sfxinfor_singular,
sfxinfor_priority,
sfxinfor_flags, // "pitch"
sfxinfor_volume,
sfxinfor_caption,
sfxinfor_skinsound
};
@ -49,6 +50,7 @@ const char *const sfxinfo_ropt[] = {
"singular",
"priority",
"flags",
"volume",
"caption",
"skinsound",
NULL};
@ -57,12 +59,14 @@ enum sfxinfo_write {
sfxinfow_singular = 0,
sfxinfow_priority,
sfxinfow_flags, // "pitch"
sfxinfow_volume,
sfxinfow_caption
};
const char *const sfxinfo_wopt[] = {
"singular",
"priority",
"flags",
"volume",
"caption",
NULL};
@ -1328,6 +1332,9 @@ static int lib_setSfxInfo(lua_State *L)
case sfxinfow_flags:
info->pitch = (INT32)luaL_checkinteger(L, 3);
break;
case sfxinfow_volume:
info->volume = (INT32)luaL_checkinteger(L, 3);
break;
case sfxinfow_caption:
strlcpy(info->caption, luaL_checkstring(L, 3), sizeof(info->caption));
break;
@ -1368,6 +1375,9 @@ static int sfxinfo_get(lua_State *L)
case sfxinfor_flags:
lua_pushinteger(L, sfx->pitch);
return 1;
case sfxinfor_volume:
lua_pushinteger(L, sfx->volume);
return 1;
case sfxinfor_caption:
lua_pushstring(L, sfx->caption);
return 1;
@ -1408,6 +1418,9 @@ static int sfxinfo_set(lua_State *L)
case sfxinfow_flags:
sfx->pitch = luaL_checkinteger(L, 1);
break;
case sfxinfow_volume:
sfx->volume = luaL_checkinteger(L, 1);
break;
case sfxinfow_caption:
strlcpy(sfx->caption, luaL_checkstring(L, 1), sizeof(sfx->caption));
break;

View file

@ -356,12 +356,6 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->trickpanel);
else if (fastcmp(field,"tricktime"))
lua_pushinteger(L, plr->tricktime);
else if (fastcmp(field,"trickmomx"))
lua_pushfixed(L, plr->trickmomx);
else if (fastcmp(field,"trickmomy"))
lua_pushfixed(L, plr->trickmomy);
else if (fastcmp(field,"trickmomz"))
lua_pushfixed(L, plr->trickmomz);
else if (fastcmp(field,"trickboostpower"))
lua_pushfixed(L, plr->trickboostpower);
else if (fastcmp(field,"trickboostdecay"))
@ -707,12 +701,6 @@ static int player_set(lua_State *L)
plr->trickpanel = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tricktime"))
plr->tricktime = luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickmomx"))
plr->trickmomx = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickmomy"))
plr->trickmomy = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickmomz"))
plr->trickmomz = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickboostpower"))
plr->trickboostpower = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickboostdecay"))

View file

@ -278,19 +278,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
break;
case MT_ITEMCAPSULE:
if (special->threshold != KITEM_SUPERRING
&& special->threshold != KITEM_SPB
&& !P_CanPickupItem(player, 1))
return;
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)
return;
if (special->scale < special->extravalue1) // don't break it while it's respawning
return;
if (special->threshold == KITEM_SPB && K_IsSPBInGame()) // don't spawn a second SPB
return;
switch (special->threshold)
{
case KITEM_SPB:
if (K_IsSPBInGame()) // don't spawn a second SPB
return;
break;
case KITEM_SUPERRING:
if (player->pflags & PF_RINGLOCK) // no cheaty rings
return;
break;
default:
if (!P_CanPickupItem(player, 1))
return;
break;
}
S_StartSound(toucher, special->info->deathsound);
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
@ -960,7 +968,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target))
return;
//K_SetHitLagForObjects(target, inflictor, 15);
//K_SetHitLagForObjects(target, inflictor, MAXHITLAGTICS, true);
// SRB2kart
// I wish I knew a better way to do this
@ -1247,6 +1255,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
kart->angle = target->angle;
kart->color = target->color;
kart->hitlag = target->hitlag;
kart->eflags |= MFE_DAMAGEHITLAG;
P_SetObjectMomZ(kart, 6*FRACUNIT, false);
kart->extravalue1 = target->player->kartweight;
}
@ -1737,7 +1746,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
}
K_DropEmeraldsFromPlayer(player, player->emeralds);
K_SetHitLagForObjects(player->mo, inflictor, 15);
K_SetHitLagForObjects(player->mo, inflictor, MAXHITLAGTICS, true);
player->carry = CR_NONE;
@ -1797,7 +1806,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
player_t *player;
boolean force = false;
INT32 laglength = 10;
INT32 laglength = 6;
INT32 kinvextend = 0;
if (objectplacing)
@ -1816,7 +1825,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (((damagetype & DMG_TYPEMASK) == DMG_STING)
|| ((inflictor && !P_MobjWasRemoved(inflictor)) && inflictor->type == MT_BANANA && inflictor->health <= 1))
{
laglength = 5;
laglength = 2;
}
// Everything above here can't be forced.
@ -1972,6 +1981,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Destroy any remainder bumpers from the player for karma comeback damage
K_DestroyBumpers(player, player->bumpers);
}
else
{
source->player->overtimekarma += 5*TICRATE;
}
if (damagetype & DMG_STEAL)
{
@ -2050,7 +2063,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
}
player->instashield = 15;
K_SetHitLagForObjects(target, inflictor, laglength);
K_SetHitLagForObjects(target, inflictor, laglength, true);
return true;
}
}
@ -2072,7 +2085,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (source && source->player && target)
G_GhostAddHit((INT32) (source->player - players), target);
K_SetHitLagForObjects(target, inflictor, laglength);
K_SetHitLagForObjects(target, inflictor, laglength, true);
if (target->health <= 0)
{
@ -2080,7 +2093,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return true;
}
//K_SetHitLagForObjects(target, inflictor, laglength);
//K_SetHitLagForObjects(target, inflictor, laglength, true);
if (player)
P_ResetPlayer(target->player);

View file

@ -398,6 +398,7 @@ void P_SetThingPosition(mobj_t *thing);
void P_SetUnderlayPosition(mobj_t *thing);
boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing);
boolean P_IsLineTripWire(const line_t *ld);
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);

View file

@ -206,11 +206,14 @@ static void add_spechit(line_t *ld)
numspechit++;
}
static boolean P_SpecialIsLinedefCrossType(UINT16 ldspecial)
static boolean P_SpecialIsLinedefCrossType(line_t *ld)
{
boolean linedefcrossspecial = false;
switch (ldspecial)
if (P_IsLineTripWire(ld))
return true;
switch (ld->special)
{
case 2001: // Finish line
case 2003: // Respawn line
@ -345,28 +348,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
}
}
if (object->player)
{
// Less friction when hitting horizontal springs
if (!vertispeed)
{
if (!object->player->tiregrease)
{
UINT8 i;
for (i = 0; i < 2; i++)
{
mobj_t *grease;
grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE);
P_SetTarget(&grease->target, object);
grease->angle = K_MomentumAngle(object);
grease->extravalue1 = i;
}
}
object->player->tiregrease = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS
}
}
// Horizontal speed is used as a minimum thrust, not a direct replacement
finalSpeed = max(objectSpeed, finalSpeed);
@ -389,6 +370,22 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
object->player->springstars = max(vertispeed, horizspeed) / FRACUNIT / 2;
object->player->springcolor = starcolor;
// Less friction when hitting springs
if (!object->player->tiregrease)
{
UINT8 i;
for (i = 0; i < 2; i++)
{
mobj_t *grease;
grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE);
P_SetTarget(&grease->target, object);
grease->angle = K_MomentumAngle(object);
grease->extravalue1 = i;
}
object->player->tiregrease = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS
}
}
return true;
@ -485,6 +482,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
|| (thing->player && thing->player->spectator))
return true;
// Ignore the collision if BOTH things are in hitlag.
if (thing->hitlag > 0 && tmthing->hitlag > 0)
return true;
if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING)))
return true;
@ -1554,6 +1555,11 @@ boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing)
}
}
boolean P_IsLineTripWire(const line_t *ld)
{
return ld->tripwire;
}
//
// PIT_CheckLine
// Adjusts tmfloorz and tmceilingz as lines are contacted
@ -1668,7 +1674,7 @@ static boolean PIT_CheckLine(line_t *ld)
tmdropoffz = lowfloor;
// we've crossed the line
if (P_SpecialIsLinedefCrossType(ld->special))
if (P_SpecialIsLinedefCrossType(ld))
{
add_spechit(ld);
}
@ -2408,11 +2414,13 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (radius < mapobjectscale)
radius = mapobjectscale;
#if 0
if (thing->hitlag > 0)
{
// Do not move during hitlag
return false;
}
#endif
do {
if (thing->flags & MF_NOCLIP) {
@ -2660,10 +2668,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
oldside = P_PointOnLineSide(oldx, oldy, ld);
if (side != oldside)
{
if (ld->special)
{
P_CrossSpecialLine(ld, oldside, thing);
}
P_CrossSpecialLine(ld, oldside, thing);
}
}
}
@ -2745,7 +2750,7 @@ static boolean PTR_GetSpecialLines(intercept_t *in)
return true;
}
if (P_SpecialIsLinedefCrossType(ld->special))
if (P_SpecialIsLinedefCrossType(ld))
{
add_spechit(ld);
}
@ -2815,10 +2820,7 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_
oldside = P_PointOnLineSide(x, y, ld);
if (side != oldside)
{
if (ld->special)
{
P_CrossSpecialLine(ld, oldside, thing);
}
P_CrossSpecialLine(ld, oldside, thing);
}
}
}
@ -3022,6 +3024,7 @@ static void P_PlayerHitBounceLine(line_t *ld)
INT32 side;
angle_t lineangle;
fixed_t movelen;
fixed_t x, y;
side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy)-ANGLE_90;
@ -3036,8 +3039,19 @@ static void P_PlayerHitBounceLine(line_t *ld)
if (slidemo->player && movelen < (15*mapobjectscale))
movelen = (15*mapobjectscale);
tmxmove += FixedMul(movelen, FINECOSINE(lineangle));
tmymove += FixedMul(movelen, FINESINE(lineangle));
x = FixedMul(movelen, FINECOSINE(lineangle));
y = FixedMul(movelen, FINESINE(lineangle));
if (P_IsLineTripWire(ld))
{
tmxmove = x * 4;
tmymove = y * 4;
}
else
{
tmxmove += x;
tmymove += y;
}
}
//
@ -3675,6 +3689,11 @@ void P_BouncePlayerMove(mobj_t *mo)
tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3)));
}
if (P_IsLineTripWire(bestslideline))
{
K_ApplyTripWire(mo->player, TRIP_BLOCKED);
}
else
{
mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP);
if (mo->eflags & MFE_VERTICALFLIP)
@ -3694,8 +3713,11 @@ void P_BouncePlayerMove(mobj_t *mo)
mo->player->cmomx = tmxmove;
mo->player->cmomy = tmymove;
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) {
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
if (!P_IsLineTripWire(bestslideline))
{
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) {
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
}
}
}

View file

@ -15,6 +15,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "k_kart.h"
#include "p_local.h"
#include "r_main.h"
#include "r_data.h"
@ -588,7 +589,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (mobj)
{
// Check for collision with front side's midtexture if Effect 4 is set
if (linedef->flags & ML_EFFECT4
if ((linedef->flags & ML_EFFECT4 || (mobj->player && P_IsLineTripWire(linedef) && !K_TripwirePass(mobj->player)))
&& !linedef->polyobj // don't do anything for polyobjects! ...for now
) {
side_t *side = &sides[linedef->sidenum[0]];

View file

@ -6889,6 +6889,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
z);
mobj->angle = ang;
if (!P_IsObjectOnGround(mobj->target))
mobj->renderflags |= RF_DONTDRAW;
if (leveltime & 1)
mobj->renderflags |= RF_DONTDRAW;
@ -8613,7 +8616,7 @@ void P_MobjThinker(mobj_t *mobj)
return;
}
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL);
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG);
tmfloorthing = tmhitthing = NULL;

View file

@ -247,6 +247,8 @@ typedef enum
MFE_TRACERANGLE = 1<<11,
// SRB2Kart: The mobj just hit & bounced off a wall, this is cleared on next frame
MFE_JUSTBOUNCEDWALL = 1<<12,
// SRB2Kart: In damage hitlag (displays different visual efx)
MFE_DAMAGEHITLAG = 1<<13,
// free: to and including 1<<15
} mobjeflag_t;

View file

@ -306,9 +306,6 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].trickpanel);
WRITEUINT8(save_p, players[i].tricktime);
WRITEUINT32(save_p, players[i].trickmomx);
WRITEUINT32(save_p, players[i].trickmomy);
WRITEUINT32(save_p, players[i].trickmomz);
WRITEUINT32(save_p, players[i].trickboostpower);
WRITEUINT8(save_p, players[i].trickboostdecay);
WRITEUINT8(save_p, players[i].trickboost);
@ -317,9 +314,11 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].emeralds);
WRITEUINT8(save_p, players[i].bumpers);
WRITEINT16(save_p, players[i].karmadelay);
WRITEUINT32(save_p, players[i].overtimekarma);
WRITEINT16(save_p, players[i].spheres);
WRITESINT8(save_p, players[i].glanceDir);
WRITEUINT8(save_p, players[i].tripWireState);
WRITEUINT8(save_p, players[i].typing_timer);
WRITEUINT8(save_p, players[i].typing_duration);
@ -334,6 +333,7 @@ static void P_NetArchivePlayers(void)
WRITEFIXED(save_p, players[i].respawn.pointz);
WRITEUINT8(save_p, players[i].respawn.flip);
WRITEUINT32(save_p, players[i].respawn.timer);
WRITEUINT32(save_p, players[i].respawn.airtimer);
WRITEUINT32(save_p, players[i].respawn.distanceleft);
WRITEUINT32(save_p, players[i].respawn.dropdash);
@ -562,9 +562,6 @@ static void P_NetUnArchivePlayers(void)
players[i].trickpanel = READUINT8(save_p);
players[i].tricktime = READUINT8(save_p);
players[i].trickmomx = READUINT32(save_p);
players[i].trickmomy = READUINT32(save_p);
players[i].trickmomz = READUINT32(save_p);
players[i].trickboostpower = READUINT32(save_p);
players[i].trickboostdecay = READUINT8(save_p);
players[i].trickboost = READUINT8(save_p);
@ -573,9 +570,11 @@ static void P_NetUnArchivePlayers(void)
players[i].emeralds = READUINT8(save_p);
players[i].bumpers = READUINT8(save_p);
players[i].karmadelay = READINT16(save_p);
players[i].overtimekarma = READUINT32(save_p);
players[i].spheres = READINT16(save_p);
players[i].glanceDir = READSINT8(save_p);
players[i].tripWireState = READUINT8(save_p);
players[i].typing_timer = READUINT8(save_p);
players[i].typing_duration = READUINT8(save_p);
@ -590,6 +589,7 @@ static void P_NetUnArchivePlayers(void)
players[i].respawn.pointz = READFIXED(save_p);
players[i].respawn.flip = (boolean)READUINT8(save_p);
players[i].respawn.timer = READUINT32(save_p);
players[i].respawn.airtimer = READUINT32(save_p);
players[i].respawn.distanceleft = READUINT32(save_p);
players[i].respawn.dropdash = READUINT32(save_p);
@ -1965,7 +1965,9 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, slope->normal.z);
}
if (diff2 & MD2_HITLAG)
{
WRITEINT32(save_p, mobj->hitlag);
}
WRITEUINT32(save_p, mobj->mobjnum);
}
@ -3057,7 +3059,9 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
slope->normal.z = READFIXED(save_p);
}
if (diff2 & MD2_HITLAG)
{
mobj->hitlag = READINT32(save_p);
}
if (diff & MD_REDFLAG)
{

View file

@ -1044,6 +1044,8 @@ static void P_InitializeLinedef(line_t *ld)
ld->validcount = 0;
ld->polyobj = NULL;
ld->tripwire = false;
ld->text = NULL;
ld->callcount = 0;
@ -1936,11 +1938,23 @@ static void P_ProcessLinedefsAfterSidedefs(void)
{
size_t i = numlines;
register line_t *ld = lines;
const INT32 TEX_TRIPWIRE = R_TextureNumForName("TRIPWIRE");
const INT32 TEX_4RIPWIRE = R_TextureNumForName("4RIPWIRE");
for (; i--; ld++)
{
INT32 midtexture = sides[ld->sidenum[0]].midtexture;
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
if (midtexture == TEX_TRIPWIRE ||
midtexture == TEX_4RIPWIRE)
{
ld->tripwire = true;
}
switch (ld->special)
{
// Compile linedef 'text' from both sidedefs 'text' for appropriate specials.

View file

@ -2018,6 +2018,12 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing)
return;
{
player_t *player = thing->player;
if (P_IsLineTripWire(line))
{
K_ApplyTripWire(player, TRIP_PASSED);
}
switch (line->special)
{
case 2001: // Finish Line

View file

@ -608,6 +608,13 @@ void P_Ticker(boolean run)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
P_PlayerAfterThink(&players[i]);
// Plays the music after the starting countdown.
if (leveltime == (starttime + (TICRATE/2)))
{
S_ChangeMusic(mapmusname, mapmusflags, true);
S_ShowMusicCredit();
}
ps_lua_thinkframe_time = I_GetPreciseTime();
LUAh_ThinkFrame();
ps_lua_thinkframe_time = I_GetPreciseTime() - ps_lua_thinkframe_time;

View file

@ -420,6 +420,8 @@ typedef struct line_s
size_t validcount; // if == validcount, already checked
polyobj_t *polyobj; // Belongs to a polyobject?
boolean tripwire;
char *text; // a concatenation of all front and back texture names, for linedef specials that require a string.
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
} line_t;

View file

@ -141,7 +141,9 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
#define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4)
#define BLINK_TT_CACHE_INDEX (MAXSKINS + 5)
#define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6)
#define TT_CACHE_SIZE (MAXSKINS + 7)
#define HITLAG_TT_CACHE_INDEX (MAXSKINS + 7)
#define TT_CACHE_SIZE (MAXSKINS + 8)
#define SKIN_RAMP_LENGTH 16
#define DEFAULT_STARTTRANSCOLOR 96
#define NUM_PALETTE_ENTRIES 256
@ -160,6 +162,7 @@ static INT32 SkinToCacheIndex(INT32 skinnum)
case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX;
case TC_BLINK: return BLINK_TT_CACHE_INDEX;
case TC_DASHMODE: return DASHMODE_TT_CACHE_INDEX;
case TC_HITLAG: return HITLAG_TT_CACHE_INDEX;
default: break;
}
@ -177,6 +180,7 @@ static INT32 CacheIndexToSkin(INT32 ttc)
case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW;
case BLINK_TT_CACHE_INDEX: return TC_BLINK;
case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE;
case HITLAG_TT_CACHE_INDEX: return TC_HITLAG;
default: break;
}

View file

@ -119,6 +119,7 @@ enum
TC_RAINBOW, // For single colour
TC_BLINK, // For item blinking, according to kart
TC_DASHMODE, // For Metal Sonic's dashmode
TC_HITLAG, // Damage hitlag effect
TC_DEFAULT
};

View file

@ -162,7 +162,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
return;
transtable = R_GetLinedefTransTable(ldef);
if (ldef->special == 910)
if (ldef->special == 910 || P_IsLineTripWire(ldef))
{
if (transtable == NUMTRANSMAPS)
transtable = 0;

View file

@ -737,7 +737,11 @@ boolean R_SpriteIsFlashing(vissprite_t *vis)
UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
{
if (R_SpriteIsFlashing(vis)) // Bosses "flash"
if (vis->mobj->hitlag > 0 && (vis->mobj->eflags & MFE_DAMAGEHITLAG))
{
return R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE);
}
else if (R_SpriteIsFlashing(vis)) // Bosses "flash"
{
if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized)
return R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
@ -1432,7 +1436,7 @@ static void R_ProjectSprite(mobj_t *thing)
#endif
// hitlag vibrating
if (thing->hitlag > 0)
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
{
fixed_t mul = thing->hitlag * (FRACUNIT / 10);

View file

@ -693,7 +693,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
channels[cnum].sfxinfo = sfx;
channels[cnum].origin = origin;
channels[cnum].volume = initial_volume;
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
channels[cnum].handle = I_StartSound(sfx_id, S_GetSoundVolume(sfx, volume), sep, pitch, priority, cnum);
}
}
@ -899,7 +899,7 @@ void S_UpdateSounds(void)
}
if (audible)
I_UpdateSoundParams(c->handle, volume, sep, pitch);
I_UpdateSoundParams(c->handle, S_GetSoundVolume(c->sfxinfo, volume), sep, pitch);
else
S_StopChannel(cnum);
}
@ -1011,6 +1011,14 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t
return FixedDiv(approx_dist, mapobjectscale); // approx_dist
}
INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume)
{
if (sfx->volume > 0)
return (volume * sfx->volume) / 100;
return volume;
}
//
// Changes volume, stereo-separation, and pitch variables
// from the norm of a sound effect to be played.

View file

@ -295,6 +295,8 @@ void S_UpdateClosedCaptions(void);
FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume);
void S_SetSfxVolume(INT32 volume);
void S_SetMusicVolume(INT32 digvolume);
#define S_SetDigMusicVolume S_SetMusicVolume

View file

@ -908,6 +908,138 @@ sfxinfo_t S_sfx[NUMSFX] =
{"mbv96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"mbv97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// SegaSonic Arcade sounds
{"ssa001", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa002", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa003", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa004", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa005", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa006", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa007", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa008", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa009", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa010", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa011", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa012", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa013", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa014", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa015", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa016", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa017", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa018", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa019", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa020", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa021", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa022", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa023", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa024", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa025", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa026", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa027", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa028", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa029", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa030", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa031", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa032", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa033", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa034", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa035", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa036", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa037", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa038", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa039", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa040", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa041", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa042", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa043", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa044", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa045", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa046", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa047", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa048", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa049", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa050", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa051", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa052", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa053", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa054", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa055", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa056", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa057", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa058", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa059", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa060", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa061", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa062", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa063", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa064", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa065", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa066", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa067", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa068", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa069", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa070", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa071", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa072", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa073", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa074", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa075", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa076", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa077", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa078", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa079", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa080", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa081", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa082", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa083", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa084", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa085", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa086", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa087", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa088", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa089", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa090", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa091", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa092", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa093", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa094", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa095", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa096", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa097", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa098", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa099", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa100", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa101", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa102", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa103", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa104", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa105", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa106", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa107", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa108", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa109", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa110", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa111", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa112", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa113", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa114", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa115", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa116", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa117", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa118", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa119", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa120", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa121", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa122", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa123", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa124", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa125", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa126", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa127", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa128", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa129", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"ssa130", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
// SRB2kart
{"slip", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Spinout
{"screec", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Tight turning screech

View file

@ -972,6 +972,138 @@ typedef enum
sfx_mbv96,
sfx_mbv97,
// SegaSonic Arcade sounds
sfx_ssa001,
sfx_ssa002,
sfx_ssa003,
sfx_ssa004,
sfx_ssa005,
sfx_ssa006,
sfx_ssa007,
sfx_ssa008,
sfx_ssa009,
sfx_ssa010,
sfx_ssa011,
sfx_ssa012,
sfx_ssa013,
sfx_ssa014,
sfx_ssa015,
sfx_ssa016,
sfx_ssa017,
sfx_ssa018,
sfx_ssa019,
sfx_ssa020,
sfx_ssa021,
sfx_ssa022,
sfx_ssa023,
sfx_ssa024,
sfx_ssa025,
sfx_ssa026,
sfx_ssa027,
sfx_ssa028,
sfx_ssa029,
sfx_ssa030,
sfx_ssa031,
sfx_ssa032,
sfx_ssa033,
sfx_ssa034,
sfx_ssa035,
sfx_ssa036,
sfx_ssa037,
sfx_ssa038,
sfx_ssa039,
sfx_ssa040,
sfx_ssa041,
sfx_ssa042,
sfx_ssa043,
sfx_ssa044,
sfx_ssa045,
sfx_ssa046,
sfx_ssa047,
sfx_ssa048,
sfx_ssa049,
sfx_ssa050,
sfx_ssa051,
sfx_ssa052,
sfx_ssa053,
sfx_ssa054,
sfx_ssa055,
sfx_ssa056,
sfx_ssa057,
sfx_ssa058,
sfx_ssa059,
sfx_ssa060,
sfx_ssa061,
sfx_ssa062,
sfx_ssa063,
sfx_ssa064,
sfx_ssa065,
sfx_ssa066,
sfx_ssa067,
sfx_ssa068,
sfx_ssa069,
sfx_ssa070,
sfx_ssa071,
sfx_ssa072,
sfx_ssa073,
sfx_ssa074,
sfx_ssa075,
sfx_ssa076,
sfx_ssa077,
sfx_ssa078,
sfx_ssa079,
sfx_ssa080,
sfx_ssa081,
sfx_ssa082,
sfx_ssa083,
sfx_ssa084,
sfx_ssa085,
sfx_ssa086,
sfx_ssa087,
sfx_ssa088,
sfx_ssa089,
sfx_ssa090,
sfx_ssa091,
sfx_ssa092,
sfx_ssa093,
sfx_ssa094,
sfx_ssa095,
sfx_ssa096,
sfx_ssa097,
sfx_ssa098,
sfx_ssa099,
sfx_ssa100,
sfx_ssa101,
sfx_ssa102,
sfx_ssa103,
sfx_ssa104,
sfx_ssa105,
sfx_ssa106,
sfx_ssa107,
sfx_ssa108,
sfx_ssa109,
sfx_ssa110,
sfx_ssa111,
sfx_ssa112,
sfx_ssa113,
sfx_ssa114,
sfx_ssa115,
sfx_ssa116,
sfx_ssa117,
sfx_ssa118,
sfx_ssa119,
sfx_ssa120,
sfx_ssa121,
sfx_ssa122,
sfx_ssa123,
sfx_ssa124,
sfx_ssa125,
sfx_ssa126,
sfx_ssa127,
sfx_ssa128,
sfx_ssa129,
sfx_ssa130,
// SRB2kart
sfx_slip,
sfx_screec,