Break the Capsules HUD tracking

This commit is contained in:
Sally Coolatta 2022-11-28 01:47:00 -05:00
parent ebd9ea579f
commit a0bcd52bf1
2 changed files with 339 additions and 4 deletions

View file

@ -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;
}

View file

@ -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);