Merge branch 'fixUnflippedImportantObjects' into 'master'

Fix unflipped important objects & elements (also fix trick treshhold when flipped)

See merge request KartKrew/RingRacers!28
This commit is contained in:
toaster 2024-08-17 18:39:39 +00:00
commit e76e2612df
9 changed files with 100 additions and 35 deletions

View file

@ -3810,24 +3810,24 @@ static boolean K_ShowPlayerNametag(player_t *p)
return true; return true;
} }
static void K_DrawLocalTagForPlayer(fixed_t x, fixed_t y, player_t *p, UINT8 id) static void K_DrawLocalTagForPlayer(fixed_t x, fixed_t y, player_t *p, UINT8 id, UINT32 flags)
{ {
UINT8 blink = ((leveltime / 7) & 1); UINT8 blink = ((leveltime / 7) & 1);
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(p->skincolor), GTC_CACHE); UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(p->skincolor), GTC_CACHE);
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_localtag[id][blink], colormap); V_DrawFixedPatch(x, y, FRACUNIT, flags, kp_localtag[id][blink], colormap);
} }
static void K_DrawRivalTagForPlayer(fixed_t x, fixed_t y) static void K_DrawRivalTagForPlayer(fixed_t x, fixed_t y, UINT32 flags)
{ {
UINT8 blink = ((leveltime / 7) & 1); UINT8 blink = ((leveltime / 7) & 1);
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_rival[blink], NULL); V_DrawFixedPatch(x, y, FRACUNIT, flags, kp_rival[blink], NULL);
} }
static void K_DrawTypingDot(fixed_t x, fixed_t y, UINT8 duration, player_t *p, INT32 flags) static void K_DrawTypingDot(fixed_t x, fixed_t y, UINT8 duration, player_t *p, INT32 flags)
{ {
if (p->typing_duration > duration) if (p->typing_duration > duration)
{ {
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN|flags, kp_typdot, NULL); V_DrawFixedPatch(x, y, FRACUNIT, flags, kp_typdot, NULL);
} }
} }
@ -3849,8 +3849,19 @@ static void K_DrawNameTagItemSpy(INT32 x, INT32 y, player_t *p, INT32 flags)
{ {
using srb2::Draw; using srb2::Draw;
bool tiny = r_splitscreen > 1; bool tiny = r_splitscreen > 1;
SINT8 flip = 1, flipboxoffset = 0;
if ((flags & V_VFLIP) == V_VFLIP)
{
// Remove the v_vflip flag - it makes things messy, but we also understand
// that we want to make this look okay for flipped players, so simply use this
// opportunity to flip vertical offsets accordingly instead.
flags &= ~V_VFLIP;
flip = P_MobjFlip(p->mo);
flipboxoffset = 8;
}
Draw bar = Draw(x, y).flags(V_NOSCALESTART|flags); Draw bar = Draw(x, y).flags(V_NOSCALESTART|flags);
Draw box = tiny ? bar.xy(-22 * vid.dupx, -17 * vid.dupy) : bar.xy(-40 * vid.dupx, -26 * vid.dupy); Draw box = tiny ? bar.xy(-22 * vid.dupx, (-17+flipboxoffset) * vid.dupy) : bar.xy(-40 * vid.dupx, (-26+flipboxoffset) * vid.dupy);
box.colorize(p->skincolor).patch(kp_itembg[tiny ? 4 : 2]); box.colorize(p->skincolor).patch(kp_itembg[tiny ? 4 : 2]);
@ -3877,8 +3888,8 @@ static void K_DrawNameTagItemSpy(INT32 x, INT32 y, player_t *p, INT32 flags)
if (p->itemamount > 1) if (p->itemamount > 1)
{ {
(tiny ? (tiny ?
bar.xy(-3 * vid.dupx, -4 * vid.dupy).font(Draw::Font::kPing) : bar.xy(-3 * vid.dupx, (-4*flip) * vid.dupy).font(Draw::Font::kPing) :
bar.xy(-4 * vid.dupx, -2 * vid.dupy).font(Draw::Font::kThinTimer) bar.xy(-4 * vid.dupx, (-2*flip) * vid.dupy).font(Draw::Font::kThinTimer)
) )
.align(Draw::Align::kRight) .align(Draw::Align::kRight)
.text("{}", p->itemamount); .text("{}", p->itemamount);
@ -3924,6 +3935,13 @@ static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p, INT32 flag
UINT8 *colormap = V_GetStringColormap(clr); UINT8 *colormap = V_GetStringColormap(clr);
INT32 barx = 0, bary = 0, barw = 0; INT32 barx = 0, bary = 0, barw = 0;
INT32 flipped = P_MobjFlip(p->mo), flipfilloffset = 0, flipfontoffset = 0, flipspheresoffset = 0;
if (flipped == -1)
{
flipfilloffset = -3; // You cannot really flip drawfill.
flipfontoffset = -9; // Accounts for font height.
flipspheresoffset = 2;
}
UINT8 cnum = R_GetViewNumber(); UINT8 cnum = R_GetViewNumber();
@ -3946,7 +3964,7 @@ static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p, INT32 flag
bary = (y * vid.dupy) / FRACUNIT; bary = (y * vid.dupy) / FRACUNIT;
barx += (6 * vid.dupx); barx += (6 * vid.dupx);
bary -= (16 * vid.dupx); bary -= ((16 + flipfilloffset) * vid.dupx) * flipped;
// Center it if necessary // Center it if necessary
if (vid.width != BASEVIDWIDTH * vid.dupx) if (vid.width != BASEVIDWIDTH * vid.dupx)
@ -3967,7 +3985,7 @@ static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p, INT32 flag
if (gametyperules & GTR_SPHERES) if (gametyperules & GTR_SPHERES)
{ {
K_DrawNameTagSphereMeter(barx, bary + (4 * vid.dupy), barw, p->spheres, flags); K_DrawNameTagSphereMeter(barx, bary + (((4 + flipspheresoffset) * vid.dupy) * P_MobjFlip(p->mo)), barw, p->spheres, flags);
} }
// Lat: 10/06/2020: colormap can be NULL on the frame you join a game, just arbitrarily use palette indexes 31 and 0 instead of whatever the colormap would give us instead to avoid crashes. // Lat: 10/06/2020: colormap can be NULL on the frame you join a game, just arbitrarily use palette indexes 31 and 0 instead of whatever the colormap would give us instead to avoid crashes.
@ -3979,7 +3997,7 @@ static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p, INT32 flag
V_DrawFixedPatch(x, y, FRACUNIT, flags, kp_nametagstem, colormap); V_DrawFixedPatch(x, y, FRACUNIT, flags, kp_nametagstem, colormap);
// Draw the name itself // Draw the name itself
V_DrawThinStringAtFixed(x + (5*FRACUNIT), y - (26*FRACUNIT), clr|flags, player_names[p - players]); V_DrawThinStringAtFixed(x + (5*FRACUNIT), y - (((26 + flipfontoffset) * FRACUNIT) * P_MobjFlip(p->mo)), clr|flags, player_names[p - players]);
} }
playertagtype_t K_WhichPlayerTag(player_t *p) playertagtype_t K_WhichPlayerTag(player_t *p)
@ -4009,19 +4027,25 @@ playertagtype_t K_WhichPlayerTag(player_t *p)
return PLAYERTAG_NONE; return PLAYERTAG_NONE;
} }
void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type, INT32 flags) void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type, boolean foreground)
{ {
INT32 flags = P_IsObjectFlipped(p->mo) ? V_VFLIP : 0;
switch (type) switch (type)
{ {
case PLAYERTAG_LOCAL: case PLAYERTAG_LOCAL:
K_DrawLocalTagForPlayer(x, y, p, G_PartyPosition(p - players)); flags |= V_HUDTRANS|V_SPLITSCREEN;
K_DrawLocalTagForPlayer(x, y, p, G_PartyPosition(p - players), flags);
break; break;
case PLAYERTAG_RIVAL: case PLAYERTAG_RIVAL:
K_DrawRivalTagForPlayer(x, y); flags |= V_HUDTRANS|V_SPLITSCREEN;
K_DrawRivalTagForPlayer(x, y, flags);
break; break;
case PLAYERTAG_NAME: case PLAYERTAG_NAME:
// We only care about the trans flag here (based?) as well as V_VFLIP.
flags |= foreground ? 0 : V_60TRANS;
K_DrawNameTagForPlayer(x, y, p, flags); K_DrawNameTagForPlayer(x, y, p, flags);
K_DrawTypingNotifier(x, y, p, flags); K_DrawTypingNotifier(x, y, p, flags);
break; break;

View file

@ -123,7 +123,7 @@ typedef enum
playertagtype_t; playertagtype_t;
playertagtype_t K_WhichPlayerTag(player_t *p); playertagtype_t K_WhichPlayerTag(player_t *p);
void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type, INT32 flags); void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type, boolean foreground);
INT32 K_GetMinimapTransFlags(const boolean usingProgressBar); INT32 K_GetMinimapTransFlags(const boolean usingProgressBar);
INT32 K_GetMinimapSplitFlags(const boolean usingProgressBar); INT32 K_GetMinimapSplitFlags(const boolean usingProgressBar);

View file

@ -466,7 +466,7 @@ void K_DrawTargetTracking(const TargetTracking& target)
{ {
if (target.nametag != PLAYERTAG_NONE) if (target.nametag != PLAYERTAG_NONE)
{ {
K_DrawPlayerTag(target.result.x, target.result.y, target.mobj->player, target.nametag, target.foreground ? 0 : V_60TRANS); K_DrawPlayerTag(target.result.x, target.result.y, target.mobj->player, target.nametag, target.foreground);
return; return;
} }

View file

@ -8647,12 +8647,20 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// GROSS. In order to have a transparent version of this for a splitscreen local player, we actually need to spawn two! // GROSS. In order to have a transparent version of this for a splitscreen local player, we actually need to spawn two!
for (doubler = 0; doubler < 2; doubler++) for (doubler = 0; doubler < 2; doubler++)
{ {
fixed_t heightOffset = player->mo->height + (24*player->mo->scale);
if (P_IsObjectFlipped(player->mo))
{
// This counteracts the offset added by K_FlipFromObject so it looks seamless from non-flipped.
heightOffset += player->mo->height - FixedMul(player->mo->scale, player->mo->height);
heightOffset *= P_MobjFlip(player->mo); // Fleep.
}
mobj_t *debtflag = P_SpawnMobj(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy, mobj_t *debtflag = P_SpawnMobj(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy,
player->mo->z + P_GetMobjZMovement(player->mo) + player->mo->height + (24*player->mo->scale), MT_THOK); player->mo->z + P_GetMobjZMovement(player->mo) + heightOffset, MT_THOK);
debtflag->old_x = player->mo->old_x; debtflag->old_x = player->mo->old_x;
debtflag->old_y = player->mo->old_y; debtflag->old_y = player->mo->old_y;
debtflag->old_z = player->mo->old_z + P_GetMobjZMovement(player->mo) + player->mo->height + (24*player->mo->scale); debtflag->old_z = player->mo->old_z + P_GetMobjZMovement(player->mo) + heightOffset;
P_SetMobjState(debtflag, S_RINGDEBT); P_SetMobjState(debtflag, S_RINGDEBT);
P_SetScale(debtflag, (debtflag->destscale = player->mo->scale)); P_SetScale(debtflag, (debtflag->destscale = player->mo->scale));
@ -9265,6 +9273,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
for(i = 0;i < 5;i++) for(i = 0;i < 5;i++)
{ {
mobj_t *aura = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height/2, MT_CHARGEAURA); mobj_t *aura = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height/2, MT_CHARGEAURA);
aura->eflags &= ~MFE_VERTICALFLIP;
aura->angle = player->mo->angle + i*ANG15; aura->angle = player->mo->angle + i*ANG15;
P_SetTarget(&aura->target, player->mo); P_SetTarget(&aura->target, player->mo);
if (i == 0) if (i == 0)
@ -11628,7 +11637,7 @@ void K_KartEbrakeVisuals(player_t *p)
{ {
if (p->ebrakefor % 20 == 0) if (p->ebrakefor % 20 == 0)
{ {
wave = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->floorz, MT_SOFTLANDING); wave = P_SpawnMobj(p->mo->x, p->mo->y, P_GetMobjGround(p->mo), MT_SOFTLANDING);
P_InstaScale(wave, p->mo->scale); P_InstaScale(wave, p->mo->scale);
P_SetTarget(&wave->target, p->mo); P_SetTarget(&wave->target, p->mo);
P_SetTarget(&wave->owner, p->mo); P_SetTarget(&wave->owner, p->mo);
@ -13276,6 +13285,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->curshield != KSHIELD_BUBBLE) if (player->curshield != KSHIELD_BUBBLE)
{ {
mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BUBBLESHIELD); mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BUBBLESHIELD);
// MT_BUBBLESHIELD doesn't have MF_NOBLOCKMAP so we need to remove this manually.
// Otherwise if you roll a bubble shield while flipped, the visuals look too mismatched.
shield->eflags &= ~MFE_VERTICALFLIP;
P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2));
P_SetTarget(&shield->target, player->mo); P_SetTarget(&shield->target, player->mo);
S_StartSound(player->mo, sfx_s3k3f); S_StartSound(player->mo, sfx_s3k3f);
@ -13624,7 +13636,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// debug shit // debug shit
//CONS_Printf("%d\n", player->mo->momz / mapobjectscale); //CONS_Printf("%d\n", player->mo->momz / mapobjectscale);
if (momz < -10*FRACUNIT) // :youfuckedup: if (momz * P_MobjFlip(player->mo) < -10*FRACUNIT) // :youfuckedup:
{ {
// tumble if you let your chance pass!! // tumble if you let your chance pass!!
player->tumbleBounces = 1; player->tumbleBounces = 1;

View file

@ -111,7 +111,10 @@ sine_bob
fixed_t sineofs) fixed_t sineofs)
{ {
hyu->sprzoff = FixedMul(HYU_VISUAL_HEIGHT * hyu->scale, hyu->sprzoff = FixedMul(HYU_VISUAL_HEIGHT * hyu->scale,
sineofs + FINESINE(a >> ANGLETOFINESHIFT)); sineofs + FINESINE(a >> ANGLETOFINESHIFT)) * P_MobjFlip(hyu);
if (P_IsObjectFlipped(hyu))
hyu->sprzoff -= hyu->height;
} }
static void static void
@ -155,11 +158,6 @@ project_hyudoro (mobj_t *hyu)
hyu->z = P_GetZAt(center->standingslope, hyu->x, hyu->y, hyu->z = P_GetZAt(center->standingslope, hyu->x, hyu->y,
P_GetMobjGround(center)); P_GetMobjGround(center));
if (P_IsObjectFlipped(hyu))
{
hyu->z -= hyu->height;
}
} }
static void static void

View file

@ -17,6 +17,7 @@
#include "../p_local.h" #include "../p_local.h"
#include "../p_mobj.h" #include "../p_mobj.h"
#include "../tables.h" #include "../tables.h"
#include "../k_kart.h"
// copied from objects/monitor.c // copied from objects/monitor.c
#define FINE90 (FINEANGLES/4) #define FINE90 (FINEANGLES/4)
@ -92,7 +93,10 @@ struct Aura : mobj_t
return; return;
} }
P_MoveOrigin(this, origin()->x, origin()->y, origin()->z); K_FlipFromObject(this, origin());
fixed_t flipoffset = P_IsObjectFlipped(origin()) ? origin()->height : 0;
P_MoveOrigin(this, origin()->x, origin()->y, origin()->z - flipoffset);
P_InstaScale(this, 11 * origin()->scale / 10); P_InstaScale(this, 11 * origin()->scale / 10);
translate(); translate();

View file

@ -29,10 +29,18 @@ void Obj_ServantHandSpawning(player_t *player)
player->handtimer++; player->handtimer++;
if (player->hand == NULL && player->handtimer == TICRATE) if (player->hand == NULL && player->handtimer == TICRATE)
{ {
fixed_t heightOffset = player->mo->height + 30*mapobjectscale;
if (P_IsObjectFlipped(player->mo))
{
// This counteracts the offset added by K_FlipFromObject so it looks seamless from non-flipped.
heightOffset += player->mo->height - FixedMul(player->mo->scale, player->mo->height);
heightOffset *= P_MobjFlip(player->mo); // Fleep.
}
mobj_t *hand = P_SpawnMobj( mobj_t *hand = P_SpawnMobj(
player->mo->x, player->mo->x,
player->mo->y, player->mo->y,
player->mo->z + player->mo->height + 30*mapobjectscale, player->mo->z + heightOffset,
MT_SERVANTHAND MT_SERVANTHAND
); );
@ -116,12 +124,16 @@ void Obj_ServantHandThink(mobj_t *hand)
hand->color = player->skincolor; hand->color = player->skincolor;
hand->angle = player->besthanddirection; hand->angle = player->besthanddirection;
fixed_t heightOffset = player->mo->height + 30*mapobjectscale;
if (P_IsObjectFlipped(player->mo))
heightOffset *= P_MobjFlip(player->mo); // Fleep.
K_FlipFromObject(hand, player->mo);
P_MoveOrigin(hand, P_MoveOrigin(hand,
player->mo->x + xoffs, player->mo->x + xoffs,
player->mo->y + yoffs, player->mo->y + yoffs,
player->mo->z + player->mo->height + 30*mapobjectscale player->mo->z + heightOffset
); );
K_FlipFromObject(hand, player->mo);
hand->sprzoff = player->mo->sprzoff; hand->sprzoff = player->mo->sprzoff;

View file

@ -93,7 +93,10 @@ sine_bob
// slightly modified from objects/hyudoro.c // slightly modified from objects/hyudoro.c
hyu->sprzoff = FixedMul(kBobHeight, hyu->sprzoff = FixedMul(kBobHeight,
sineofs + FINESINE(a >> ANGLETOFINESHIFT)); sineofs + FINESINE(a >> ANGLETOFINESHIFT)) * P_MobjFlip(hyu);
if (P_IsObjectFlipped(hyu))
hyu->sprzoff -= hyu->height;
} }
void void
@ -303,6 +306,7 @@ struct Flicky : mobj_t
color = super_color(); color = super_color();
} }
K_FlipFromObject(this, source());
bob_in_place(this, phase() * 8, 32); bob_in_place(this, phase() * 8, 32);
} }

View file

@ -8355,6 +8355,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
P_SetScale(mobj, (mobj->destscale = (5*mobj->target->scale)>>2)); P_SetScale(mobj, (mobj->destscale = (5*mobj->target->scale)>>2));
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2);
// Taken from K_FlipFromObject. We just want to flip the visual according to its target, but that's it.
mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP);
break; break;
} }
case MT_BUBBLESHIELD: case MT_BUBBLESHIELD:
@ -8461,8 +8464,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
mobj->extravalue2 = mobj->target->player->bubbleblowup; mobj->extravalue2 = mobj->target->player->bubbleblowup;
P_SetScale(mobj, (mobj->destscale = scale)); P_SetScale(mobj, (mobj->destscale = scale));
// For some weird reason, the Bubble Shield is the exception flip-wise, it has the offset baked into the sprite.
// So instead of simply flipping the object, we have to do a position offset.
fixed_t positionOffset = 0;
if (P_IsObjectFlipped(mobj->target))
positionOffset -= 8 * mobj->scale;
mobj->flags &= ~(MF_NOCLIPTHING); mobj->flags &= ~(MF_NOCLIPTHING);
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + positionOffset);
mobj->flags |= MF_NOCLIPTHING; mobj->flags |= MF_NOCLIPTHING;
break; break;
} }
@ -8550,6 +8559,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
} }
} }
// Taken from K_FlipFromObject. We just want to flip the visual according to its target, but that's it.
mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP);
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2);
mobj->angle = K_MomentumAngle(mobj->target); mobj->angle = K_MomentumAngle(mobj->target);
@ -10552,8 +10563,8 @@ void P_SceneryThinker(mobj_t *mobj)
if (!P_MobjWasRemoved(mobj->target)) if (!P_MobjWasRemoved(mobj->target))
{ {
// Cast like a shadow on the ground // Cast like a shadow on the ground
P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->floorz); P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, P_GetMobjGround(mobj->target));
mobj->standingslope = mobj->target->standingslope; mobj->standingslope = P_IsObjectOnGround(mobj->target) ? mobj->target->standingslope : NULL;
if (!P_IsObjectOnGround(mobj->target) && mobj->target->momz < -24 * mapobjectscale) if (!P_IsObjectOnGround(mobj->target) && mobj->target->momz < -24 * mapobjectscale)
{ {