mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-28 04:51:42 +00:00
Merge branch 'spraycan-aura' into 'master'
Add HUD trackers for Spraycans (all variants), add missing variants for normal + Super Flicky HUD trackers, add shadow for Spraycans Closes #649 and #662 See merge request KartKrew/Kart!1461
This commit is contained in:
commit
a11ba48a0a
4 changed files with 194 additions and 45 deletions
64
src/k_hud.c
64
src/k_hud.c
|
|
@ -197,11 +197,14 @@ patch_t *kp_autoroulette;
|
||||||
|
|
||||||
patch_t *kp_capsuletarget_arrow[2][2];
|
patch_t *kp_capsuletarget_arrow[2][2];
|
||||||
patch_t *kp_capsuletarget_icon[2];
|
patch_t *kp_capsuletarget_icon[2];
|
||||||
patch_t *kp_capsuletarget_far[2];
|
patch_t *kp_capsuletarget_far[2][2];
|
||||||
patch_t *kp_capsuletarget_far_text[2];
|
patch_t *kp_capsuletarget_far_text[2];
|
||||||
patch_t *kp_capsuletarget_near[8];
|
patch_t *kp_capsuletarget_near[2][8];
|
||||||
|
|
||||||
patch_t *kp_superflickytarget[4];
|
patch_t *kp_superflickytarget[2][4];
|
||||||
|
|
||||||
|
patch_t *kp_spraycantarget_far[2][6];
|
||||||
|
patch_t *kp_spraycantarget_near[2][6];
|
||||||
|
|
||||||
patch_t *kp_button_a[2][2];
|
patch_t *kp_button_a[2][2];
|
||||||
patch_t *kp_button_b[2][2];
|
patch_t *kp_button_b[2][2];
|
||||||
|
|
@ -758,23 +761,72 @@ void K_LoadKartHUDGraphics(void)
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
buffer[7] = '0'+i;
|
buffer[7] = '0'+i;
|
||||||
HU_UpdatePatch(&kp_capsuletarget_far[i], "%s", buffer);
|
HU_UpdatePatch(&kp_capsuletarget_far[0][i], "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "HUDC4PBx");
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
buffer[7] = '0'+i;
|
||||||
|
HU_UpdatePatch(&kp_capsuletarget_far[1][i], "%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(buffer, "HUDCAPAx");
|
sprintf(buffer, "HUDCAPAx");
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
buffer[7] = '0'+i;
|
buffer[7] = '0'+i;
|
||||||
HU_UpdatePatch(&kp_capsuletarget_near[i], "%s", buffer);
|
HU_UpdatePatch(&kp_capsuletarget_near[0][i], "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "HUDC4PAx");
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
buffer[7] = '0'+i;
|
||||||
|
HU_UpdatePatch(&kp_capsuletarget_near[1][i], "%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(buffer, "HUDFLKAx");
|
sprintf(buffer, "HUDFLKAx");
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
buffer[7] = '0'+i;
|
buffer[7] = '0'+i;
|
||||||
HU_UpdatePatch(&kp_superflickytarget[i], "%s", buffer);
|
HU_UpdatePatch(&kp_superflickytarget[0][i], "%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "H4PFLKAx");
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
buffer[7] = '0'+i;
|
||||||
|
HU_UpdatePatch(&kp_superflickytarget[1][i], "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "SPCNBFAx");
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
buffer[7] = '1'+i;
|
||||||
|
HU_UpdatePatch(&kp_spraycantarget_far[0][i], "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "SPCNSFAx");
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
buffer[7] = '1'+i;
|
||||||
|
HU_UpdatePatch(&kp_spraycantarget_far[1][i], "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "SPCNBCLx");
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
buffer[7] = '1'+i;
|
||||||
|
HU_UpdatePatch(&kp_spraycantarget_near[0][i], "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "SPCNSCLx");
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
buffer[7] = '1'+i;
|
||||||
|
HU_UpdatePatch(&kp_spraycantarget_near[1][i], "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
K_LoadButtonGraphics(kp_button_a[0], 'A');
|
K_LoadButtonGraphics(kp_button_a[0], 'A');
|
||||||
K_LoadButtonGraphics(kp_button_a[1], 'N');
|
K_LoadButtonGraphics(kp_button_a[1], 'N');
|
||||||
K_LoadButtonGraphics(kp_button_b[0], 'B');
|
K_LoadButtonGraphics(kp_button_b[0], 'B');
|
||||||
|
|
|
||||||
|
|
@ -55,11 +55,14 @@ void K_DrawSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean isSmall);
|
||||||
|
|
||||||
extern patch_t *kp_capsuletarget_arrow[2][2];
|
extern patch_t *kp_capsuletarget_arrow[2][2];
|
||||||
extern patch_t *kp_capsuletarget_icon[2];
|
extern patch_t *kp_capsuletarget_icon[2];
|
||||||
extern patch_t *kp_capsuletarget_far[2];
|
extern patch_t *kp_capsuletarget_far[2][2];
|
||||||
extern patch_t *kp_capsuletarget_far_text[2];
|
extern patch_t *kp_capsuletarget_far_text[2];
|
||||||
extern patch_t *kp_capsuletarget_near[8];
|
extern patch_t *kp_capsuletarget_near[2][8];
|
||||||
|
|
||||||
extern patch_t *kp_superflickytarget[4];
|
extern patch_t *kp_superflickytarget[2][4];
|
||||||
|
|
||||||
|
extern patch_t *kp_spraycantarget_far[2][6];
|
||||||
|
extern patch_t *kp_spraycantarget_near[2][6];
|
||||||
|
|
||||||
extern patch_t *kp_autoroulette;
|
extern patch_t *kp_autoroulette;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "core/static_vec.hpp"
|
#include "core/static_vec.hpp"
|
||||||
|
|
@ -18,6 +19,11 @@
|
||||||
#include "st_stuff.h"
|
#include "st_stuff.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#undef near
|
||||||
|
#undef far
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace srb2;
|
using namespace srb2;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
@ -25,6 +31,28 @@ namespace
|
||||||
|
|
||||||
struct TargetTracking
|
struct TargetTracking
|
||||||
{
|
{
|
||||||
|
static constexpr int kMaxLayers = 2;
|
||||||
|
|
||||||
|
struct Animation
|
||||||
|
{
|
||||||
|
int frames;
|
||||||
|
int tics_per_frame;
|
||||||
|
StaticVec<patch_t**, kMaxLayers> layers;
|
||||||
|
int32_t video_flags = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Graphics
|
||||||
|
{
|
||||||
|
struct SplitscreenPair
|
||||||
|
{
|
||||||
|
Animation p1;
|
||||||
|
std::optional<Animation> p4;
|
||||||
|
};
|
||||||
|
|
||||||
|
SplitscreenPair near;
|
||||||
|
std::optional<SplitscreenPair> far;
|
||||||
|
};
|
||||||
|
|
||||||
mobj_t* mobj;
|
mobj_t* mobj;
|
||||||
vector3_t point;
|
vector3_t point;
|
||||||
fixed_t camDist;
|
fixed_t camDist;
|
||||||
|
|
@ -45,11 +73,36 @@ struct TargetTracking
|
||||||
|
|
||||||
case MT_SUPER_FLICKY:
|
case MT_SUPER_FLICKY:
|
||||||
return static_cast<skincolornum_t>(Obj_SuperFlickyOwner(mobj)->color);
|
return static_cast<skincolornum_t>(Obj_SuperFlickyOwner(mobj)->color);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return SKINCOLOR_NONE;
|
return SKINCOLOR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Animation animation() const
|
||||||
|
{
|
||||||
|
const fixed_t farDistance = 1280 * mapobjectscale;
|
||||||
|
bool useNear = (camDist < farDistance);
|
||||||
|
|
||||||
|
Graphics gfx = graphics();
|
||||||
|
Graphics::SplitscreenPair& pair = useNear || !gfx.far ? gfx.near : *gfx.far;
|
||||||
|
Animation& anim = r_splitscreen <= 1 || !pair.p4 ? pair.p1 : *pair.p4;
|
||||||
|
|
||||||
|
return anim;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool uses_off_screen_arrow() const
|
||||||
|
{
|
||||||
|
switch (mobj->type)
|
||||||
|
{
|
||||||
|
case MT_SPRAYCAN:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StaticVec<uint32_t, 7> player_emeralds_vec() const
|
StaticVec<uint32_t, 7> player_emeralds_vec() const
|
||||||
{
|
{
|
||||||
StaticVec<uint32_t, 7> emeralds;
|
StaticVec<uint32_t, 7> emeralds;
|
||||||
|
|
@ -100,6 +153,45 @@ struct TargetTracking
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Graphics graphics() const
|
||||||
|
{
|
||||||
|
switch (mobj->type)
|
||||||
|
{
|
||||||
|
case MT_SUPER_FLICKY:
|
||||||
|
return {
|
||||||
|
{ // Near
|
||||||
|
{4, 2, {kp_superflickytarget[0]}}, // 1P
|
||||||
|
{{4, 2, {kp_superflickytarget[1]}}}, // 4P
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
case MT_SPRAYCAN:
|
||||||
|
return {
|
||||||
|
{ // Near
|
||||||
|
{6, 2, {kp_spraycantarget_near[0]}, V_ADD}, // 1P
|
||||||
|
{{6, 2, {kp_spraycantarget_near[1]}, V_ADD}}, // 4P
|
||||||
|
},
|
||||||
|
{{ // Far
|
||||||
|
{6, 2, {kp_spraycantarget_far[0]}, V_ADD}, // 1P
|
||||||
|
{{6, 2, {kp_spraycantarget_far[1]}, V_ADD}}, // 4P
|
||||||
|
}},
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
{ // Near
|
||||||
|
{8, 2, {kp_capsuletarget_near[0]}}, // 1P
|
||||||
|
{{8, 2, {kp_capsuletarget_near[1]}}}, // 4P
|
||||||
|
},
|
||||||
|
{{ // Far
|
||||||
|
{2, 3, {kp_capsuletarget_far[0], kp_capsuletarget_far_text}}, // 1P
|
||||||
|
{{2, 3, {kp_capsuletarget_far[1]}}}, // 4P
|
||||||
|
}},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void K_DrawTargetTracking(const TargetTracking& target)
|
void K_DrawTargetTracking(const TargetTracking& target)
|
||||||
|
|
@ -116,6 +208,11 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
||||||
// Off-screen, draw alongside the borders of the screen.
|
// Off-screen, draw alongside the borders of the screen.
|
||||||
// Probably the most complicated thing.
|
// Probably the most complicated thing.
|
||||||
|
|
||||||
|
if (target.uses_off_screen_arrow() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t scrVal = 240;
|
int32_t scrVal = 240;
|
||||||
vector2_t screenSize = {};
|
vector2_t screenSize = {};
|
||||||
|
|
||||||
|
|
@ -265,54 +362,23 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Draw simple overlay.
|
// Draw simple overlay.
|
||||||
const fixed_t farDistance = 1280 * mapobjectscale;
|
vector2_t targetPos = {result.x, result.y};
|
||||||
bool useNear = (target.camDist < farDistance);
|
|
||||||
|
|
||||||
vector2_t targetPos = {};
|
TargetTracking::Animation anim = target.animation();
|
||||||
|
|
||||||
bool visible = P_CheckSight(stplyr->mo, target.mobj);
|
for (patch_t** array : anim.layers)
|
||||||
|
|
||||||
if ((visible == false || target.mobj->type == MT_SUPER_FLICKY) && (leveltime & 1))
|
|
||||||
{
|
{
|
||||||
// Flicker when not visible.
|
patch_t* patch = array[(leveltime / anim.tics_per_frame) % anim.frames];
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
targetPos.x = result.x;
|
|
||||||
targetPos.y = result.y;
|
|
||||||
|
|
||||||
auto draw = [&](patch_t* patch)
|
|
||||||
{
|
|
||||||
V_DrawFixedPatch(
|
V_DrawFixedPatch(
|
||||||
targetPos.x - ((patch->width << FRACBITS) >> 1),
|
targetPos.x - ((patch->width << FRACBITS) >> 1),
|
||||||
targetPos.y - ((patch->height << FRACBITS) >> 1),
|
targetPos.y - ((patch->height << FRACBITS) >> 1),
|
||||||
FRACUNIT,
|
FRACUNIT,
|
||||||
V_SPLITSCREEN,
|
V_SPLITSCREEN | anim.video_flags,
|
||||||
patch,
|
patch,
|
||||||
colormap
|
colormap
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (target.mobj->type == MT_SUPER_FLICKY)
|
|
||||||
{
|
|
||||||
timer = (leveltime / 2);
|
|
||||||
draw(kp_superflickytarget[timer % 4]);
|
|
||||||
}
|
|
||||||
else if (useNear == true)
|
|
||||||
{
|
|
||||||
timer = (leveltime / 2);
|
|
||||||
draw(kp_capsuletarget_near[timer % 8]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timer = (leveltime / 3);
|
|
||||||
draw(kp_capsuletarget_far[timer & 1]);
|
|
||||||
|
|
||||||
if (r_splitscreen <= 1)
|
|
||||||
{
|
|
||||||
draw(kp_capsuletarget_far_text[timer & 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -390,11 +456,32 @@ bool is_object_tracking_target(const mobj_t* mobj)
|
||||||
case MT_SUPER_FLICKY:
|
case MT_SUPER_FLICKY:
|
||||||
return Obj_IsSuperFlickyTargettingYou(mobj, stplyr->mo);
|
return Obj_IsSuperFlickyTargettingYou(mobj, stplyr->mo);
|
||||||
|
|
||||||
|
case MT_SPRAYCAN:
|
||||||
|
return !(mobj->renderflags & (RF_TRANSMASK | RF_DONTDRAW)); // the spraycan wasn't collected yet
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_object_visible(mobj_t* mobj)
|
||||||
|
{
|
||||||
|
switch (mobj->type)
|
||||||
|
{
|
||||||
|
case MT_SUPER_FLICKY:
|
||||||
|
// Always flickers.
|
||||||
|
return (leveltime & 1);
|
||||||
|
|
||||||
|
case MT_SPRAYCAN:
|
||||||
|
// Flickers, but only when visible.
|
||||||
|
return P_CheckSight(stplyr->mo, mobj) && (leveltime & 1);
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Flicker when not visible.
|
||||||
|
return P_CheckSight(stplyr->mo, mobj) || (leveltime & 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}; // namespace
|
}; // namespace
|
||||||
|
|
||||||
void K_drawTargetHUD(const vector3_t* origin, player_t* player)
|
void K_drawTargetHUD(const vector3_t* origin, player_t* player)
|
||||||
|
|
@ -418,6 +505,11 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_object_visible(mobj) == false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
vector3_t pos = {
|
vector3_t pos = {
|
||||||
R_InterpolateFixed(mobj->old_x, mobj->x) + mobj->sprxoff,
|
R_InterpolateFixed(mobj->old_x, mobj->x) + mobj->sprxoff,
|
||||||
R_InterpolateFixed(mobj->old_y, mobj->y) + mobj->spryoff,
|
R_InterpolateFixed(mobj->old_y, mobj->y) + mobj->spryoff,
|
||||||
|
|
|
||||||
|
|
@ -5342,6 +5342,7 @@ static boolean P_IsTrackerType(INT32 type)
|
||||||
case MT_EMERALD:
|
case MT_EMERALD:
|
||||||
case MT_BATTLEUFO:
|
case MT_BATTLEUFO:
|
||||||
case MT_SUPER_FLICKY:
|
case MT_SUPER_FLICKY:
|
||||||
|
case MT_SPRAYCAN:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -10412,6 +10413,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
||||||
case MT_SPECIAL_UFO:
|
case MT_SPECIAL_UFO:
|
||||||
case MT_CDUFO:
|
case MT_CDUFO:
|
||||||
case MT_BATTLEUFO:
|
case MT_BATTLEUFO:
|
||||||
|
case MT_SPRAYCAN:
|
||||||
thing->shadowscale = FRACUNIT;
|
thing->shadowscale = FRACUNIT;
|
||||||
break;
|
break;
|
||||||
case MT_SMALLMACE:
|
case MT_SMALLMACE:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue