mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-10 00:34:32 +00:00
Break the Capsules HUD tracking
This commit is contained in:
parent
ebd9ea579f
commit
a0bcd52bf1
2 changed files with 339 additions and 4 deletions
341
src/k_hud.c
341
src/k_hud.c
|
|
@ -172,6 +172,11 @@ static patch_t *kp_bossret[4];
|
|||
|
||||
static patch_t *kp_trickcool[2];
|
||||
|
||||
static patch_t *kp_capsuletarget_arrow[2][2];
|
||||
static patch_t *kp_capsuletarget_icon[2];
|
||||
static patch_t *kp_capsuletarget_far[2];
|
||||
static patch_t *kp_capsuletarget_near[8];
|
||||
|
||||
void K_LoadKartHUDGraphics(void)
|
||||
{
|
||||
INT32 i, j, k;
|
||||
|
|
@ -643,6 +648,39 @@ void K_LoadKartHUDGraphics(void)
|
|||
buffer[7] = '0'+((i+1)%10);
|
||||
HU_UpdatePatch(&kp_bossret[i], "%s", buffer);
|
||||
}
|
||||
|
||||
sprintf(buffer, "HCAPARxx");
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
buffer[6] = 'A'+i;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
buffer[7] = '0'+j;
|
||||
HU_UpdatePatch(&kp_capsuletarget_arrow[i][j], "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buffer, "HUDCAPCx");
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
buffer[7] = '0'+i;
|
||||
HU_UpdatePatch(&kp_capsuletarget_icon[i], "%s", buffer);
|
||||
}
|
||||
|
||||
sprintf(buffer, "HUDCAPBx");
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
buffer[7] = '0'+i;
|
||||
HU_UpdatePatch(&kp_capsuletarget_far[i], "%s", buffer);
|
||||
}
|
||||
|
||||
sprintf(buffer, "HUDCAPAx");
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
buffer[7] = '0'+i;
|
||||
HU_UpdatePatch(&kp_capsuletarget_near[i], "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// For the item toggle menu
|
||||
|
|
@ -888,7 +926,7 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean revers
|
|||
fixed_t fovDiff, fov, fovTangent, fg;
|
||||
|
||||
fixed_t h;
|
||||
INT32 da;
|
||||
INT32 da, dp;
|
||||
|
||||
UINT8 cameraNum = R_GetViewNumber();
|
||||
|
||||
|
|
@ -949,6 +987,7 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean revers
|
|||
// Determine viewpoint factors.
|
||||
h = R_PointToDist2(point->x, point->y, viewx, viewy);
|
||||
da = AngleDeltaSigned(viewpointAngle, R_PointToAngle2(point->x, point->y, viewx, viewy));
|
||||
dp = AngleDeltaSigned(viewpointAiming, R_PointToAngle2(0, 0, h, viewz));
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
|
|
@ -959,6 +998,10 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean revers
|
|||
result->x = FixedMul(NEWTAN(da), fg);
|
||||
result->y = FixedMul((NEWTAN(viewpointAiming) - FixedDiv((viewz - point->z), 1 + FixedMul(NEWCOS(da), h))), fg);
|
||||
|
||||
result->angle = da;
|
||||
result->pitch = dp;
|
||||
result->fov = fg;
|
||||
|
||||
// Rotate for screen roll...
|
||||
if (viewpointRoll)
|
||||
{
|
||||
|
|
@ -3070,6 +3113,217 @@ static void K_DrawWeakSpot(weakspotdraw_t *ws)
|
|||
V_DrawFixedPatch(ws->x, ws->y, FRACUNIT, 0, kp_bossret[j+1], colormap);
|
||||
}
|
||||
|
||||
typedef struct capsuletracking_s
|
||||
{
|
||||
mobj_t *mobj;
|
||||
vector3_t point;
|
||||
fixed_t camDist;
|
||||
} capsuletracking_t;
|
||||
|
||||
static void K_DrawCapsuleTracking(capsuletracking_t *caps)
|
||||
{
|
||||
trackingResult_t result = {0};
|
||||
INT32 timer = 0;
|
||||
|
||||
K_ObjectTracking(&result, &caps->point, false);
|
||||
|
||||
if (result.onScreen == false)
|
||||
{
|
||||
// Off-screen, draw alongside the borders of the screen.
|
||||
// Probably the most complicated thing.
|
||||
|
||||
INT32 scrVal = 240;
|
||||
vector2_t screenSize = {0};
|
||||
|
||||
INT32 borderSize = 7;
|
||||
vector2_t borderWin = {0};
|
||||
vector2_t borderDir = {0};
|
||||
fixed_t borderLen = FRACUNIT;
|
||||
|
||||
vector2_t arrowDir = {0};
|
||||
|
||||
vector2_t arrowPos = {0};
|
||||
patch_t *arrowPatch = NULL;
|
||||
INT32 arrowFlags = 0;
|
||||
|
||||
vector2_t capsulePos = {0};
|
||||
patch_t *capsulePatch = NULL;
|
||||
|
||||
timer = (leveltime / 3);
|
||||
|
||||
screenSize.x = vid.width / vid.dupx;
|
||||
screenSize.y = vid.height / vid.dupy;
|
||||
|
||||
if (r_splitscreen >= 2)
|
||||
{
|
||||
// Half-wide screens
|
||||
screenSize.x >>= 1;
|
||||
borderSize >>= 1;
|
||||
}
|
||||
|
||||
if (r_splitscreen >= 1)
|
||||
{
|
||||
// Half-tall screens
|
||||
screenSize.y >>= 1;
|
||||
}
|
||||
|
||||
scrVal = max(screenSize.x, screenSize.y) - 80;
|
||||
|
||||
borderWin.x = screenSize.x - borderSize;
|
||||
borderWin.y = screenSize.y - borderSize;
|
||||
|
||||
arrowDir.x = 0;
|
||||
arrowDir.y = P_MobjFlip(caps->mobj) * FRACUNIT;
|
||||
|
||||
// Simply pointing towards the result doesn't work, so inaccurate hack...
|
||||
borderDir.x = FixedMul(
|
||||
FixedMul(
|
||||
FINESINE((-result.angle >> ANGLETOFINESHIFT) & FINEMASK),
|
||||
FINECOSINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK)
|
||||
),
|
||||
result.fov
|
||||
);
|
||||
|
||||
borderDir.y = FixedMul(
|
||||
FINESINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK),
|
||||
result.fov
|
||||
);
|
||||
|
||||
borderLen = R_PointToDist2(0, 0, borderDir.x, borderDir.y);
|
||||
|
||||
if (borderLen > 0)
|
||||
{
|
||||
borderDir.x = FixedDiv(borderDir.x, borderLen);
|
||||
borderDir.y = FixedDiv(borderDir.y, borderLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Eh just put it at the bottom.
|
||||
borderDir.x = 0;
|
||||
borderDir.y = FRACUNIT;
|
||||
}
|
||||
|
||||
capsulePatch = kp_capsuletarget_icon[timer & 1];
|
||||
|
||||
if (abs(borderDir.x) > abs(borderDir.y))
|
||||
{
|
||||
// Horizontal arrow
|
||||
arrowPatch = kp_capsuletarget_arrow[1][timer & 1];
|
||||
arrowDir.y = 0;
|
||||
|
||||
if (borderDir.x < 0)
|
||||
{
|
||||
// LEFT
|
||||
arrowDir.x = -FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// RIGHT
|
||||
arrowDir.x = FRACUNIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Vertical arrow
|
||||
arrowPatch = kp_capsuletarget_arrow[0][timer & 1];
|
||||
arrowDir.x = 0;
|
||||
|
||||
if (borderDir.y < 0)
|
||||
{
|
||||
// UP
|
||||
arrowDir.y = -FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// DOWN
|
||||
arrowDir.y = FRACUNIT;
|
||||
}
|
||||
}
|
||||
|
||||
arrowPos.x = (screenSize.x >> 1) + FixedMul(scrVal, borderDir.x);
|
||||
arrowPos.y = (screenSize.y >> 1) + FixedMul(scrVal, borderDir.y);
|
||||
|
||||
arrowPos.x = min(max(arrowPos.x, borderSize), borderWin.x) * FRACUNIT;
|
||||
arrowPos.y = min(max(arrowPos.y, borderSize), borderWin.y) * FRACUNIT;
|
||||
|
||||
capsulePos.x = arrowPos.x - (arrowDir.x * 12);
|
||||
capsulePos.y = arrowPos.y - (arrowDir.y * 12);
|
||||
|
||||
arrowPos.x -= (arrowPatch->width << FRACBITS) >> 1;
|
||||
arrowPos.y -= (arrowPatch->height << FRACBITS) >> 1;
|
||||
|
||||
capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1;
|
||||
capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1;
|
||||
|
||||
if (arrowDir.x < 0)
|
||||
{
|
||||
arrowPos.x += arrowPatch->width << FRACBITS;
|
||||
arrowFlags |= V_FLIP;
|
||||
}
|
||||
|
||||
if (arrowDir.y < 0)
|
||||
{
|
||||
arrowPos.y += arrowPatch->height << FRACBITS;
|
||||
arrowFlags |= V_VFLIP;
|
||||
}
|
||||
|
||||
V_DrawFixedPatch(
|
||||
capsulePos.x, capsulePos.y,
|
||||
FRACUNIT,
|
||||
V_SPLITSCREEN,
|
||||
capsulePatch, NULL
|
||||
);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
arrowPos.x, arrowPos.y,
|
||||
FRACUNIT,
|
||||
V_SPLITSCREEN | arrowFlags,
|
||||
arrowPatch, NULL
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw simple overlay.
|
||||
const fixed_t farDistance = 1280*mapobjectscale;
|
||||
boolean useNear = (caps->camDist < farDistance);
|
||||
|
||||
patch_t *capsulePatch = NULL;
|
||||
vector2_t capsulePos = {0};
|
||||
|
||||
boolean visible = P_CheckSight(stplyr->mo, caps->mobj);
|
||||
|
||||
if (visible == false && (leveltime & 1))
|
||||
{
|
||||
// Flicker when not visible.
|
||||
return;
|
||||
}
|
||||
|
||||
capsulePos.x = result.x;
|
||||
capsulePos.y = result.y;
|
||||
|
||||
if (useNear == true)
|
||||
{
|
||||
timer = (leveltime / 2);
|
||||
capsulePatch = kp_capsuletarget_near[timer % 8];
|
||||
}
|
||||
else
|
||||
{
|
||||
timer = (leveltime / 3);
|
||||
capsulePatch = kp_capsuletarget_far[timer & 1];
|
||||
}
|
||||
|
||||
capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1;
|
||||
capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1;
|
||||
|
||||
V_DrawFixedPatch(
|
||||
capsulePos.x, capsulePos.y,
|
||||
FRACUNIT,
|
||||
V_SPLITSCREEN,
|
||||
capsulePatch, NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_drawKartNameTags(void)
|
||||
{
|
||||
const fixed_t maxdistance = 8192*mapobjectscale;
|
||||
|
|
@ -3078,7 +3332,7 @@ static void K_drawKartNameTags(void)
|
|||
UINT8 tobesorted[MAXPLAYERS];
|
||||
fixed_t sortdist[MAXPLAYERS];
|
||||
UINT8 sortlen = 0;
|
||||
UINT8 i, j;
|
||||
size_t i, j;
|
||||
|
||||
if (stplyr == NULL || stplyr->mo == NULL || P_MobjWasRemoved(stplyr->mo))
|
||||
{
|
||||
|
|
@ -3169,6 +3423,85 @@ static void K_drawKartNameTags(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (battlecapsules == true)
|
||||
{
|
||||
#define MAX_CAPSULE_HUD 32
|
||||
capsuletracking_t capsuleList[MAX_CAPSULE_HUD];
|
||||
size_t capsuleListLen = 0;
|
||||
|
||||
mobj_t *mobj = NULL;
|
||||
mobj_t *next = NULL;
|
||||
|
||||
for (mobj = kitemcap; mobj; mobj = next)
|
||||
{
|
||||
capsuletracking_t *caps = NULL;
|
||||
|
||||
next = mobj->itnext;
|
||||
|
||||
if (mobj->health <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mobj->type != MT_BATTLECAPSULE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
caps = &capsuleList[capsuleListLen];
|
||||
|
||||
caps->mobj = mobj;
|
||||
caps->point.x = R_InterpolateFixed(mobj->old_x, mobj->x);
|
||||
caps->point.y = R_InterpolateFixed(mobj->old_y, mobj->y);
|
||||
caps->point.z = R_InterpolateFixed(mobj->old_z, mobj->z);
|
||||
caps->point.z += (mobj->height >> 1);
|
||||
caps->camDist = R_PointToDist2(c.x, c.y, caps->point.x, caps->point.y);
|
||||
|
||||
capsuleListLen++;
|
||||
|
||||
if (capsuleListLen >= MAX_CAPSULE_HUD)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (capsuleListLen > 0)
|
||||
{
|
||||
// Sort by distance from camera.
|
||||
if (capsuleListLen > 1)
|
||||
{
|
||||
for (i = 0; i < capsuleListLen-1; i++)
|
||||
{
|
||||
size_t swap = i;
|
||||
|
||||
for (j = i + 1; j < capsuleListLen; j++)
|
||||
{
|
||||
capsuletracking_t *cj = &capsuleList[j];
|
||||
capsuletracking_t *cSwap = &capsuleList[swap];
|
||||
|
||||
if (cj->camDist > cSwap->camDist)
|
||||
{
|
||||
swap = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (swap != i)
|
||||
{
|
||||
capsuletracking_t temp = capsuleList[swap];
|
||||
capsuleList[swap] = capsuleList[i];
|
||||
capsuleList[i] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < capsuleListLen; i++)
|
||||
{
|
||||
K_DrawCapsuleTracking(&capsuleList[i]);
|
||||
}
|
||||
}
|
||||
#undef MAX_CAPSULE_HUD
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *ntplayer = &players[i];
|
||||
|
|
@ -3283,7 +3616,7 @@ static void K_drawKartNameTags(void)
|
|||
{
|
||||
if (!(demo.playback == true && demo.freecam == true))
|
||||
{
|
||||
for (j = 0; j <= r_splitscreen; j++)
|
||||
for (j = 0; j <= (unsigned)r_splitscreen; j++)
|
||||
{
|
||||
if (ntplayer == &players[displayplayers[j]])
|
||||
{
|
||||
|
|
@ -3291,7 +3624,7 @@ static void K_drawKartNameTags(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (j <= r_splitscreen && j != cnum)
|
||||
if (j <= (unsigned)r_splitscreen && j != cnum)
|
||||
{
|
||||
localindicator = j;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ typedef struct trackingResult_s
|
|||
fixed_t x, y;
|
||||
fixed_t scale;
|
||||
boolean onScreen;
|
||||
INT32 angle, pitch;
|
||||
fixed_t fov;
|
||||
} trackingResult_t;
|
||||
|
||||
void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean reverse);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue