mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-22 02:00:11 +00:00
Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart into srb2-tidy
# Conflicts: # src/p_mobj.c
This commit is contained in:
commit
106553f89d
33 changed files with 778 additions and 644 deletions
|
|
@ -876,8 +876,10 @@ consvar_t cv_debugrank = PlayerCheat("debugrank", "Off").description("Show GP ra
|
|||
});
|
||||
|
||||
consvar_t cv_debugrender_contrast = PlayerCheat("debugrender_contrast", "0.0").floating_point().min_max(-FRACUNIT, FRACUNIT).description("Change level lighting");
|
||||
consvar_t cv_debugrender_freezebsp = PlayerCheat("debugrender_freezebsp", "Off").on_off().description("Freeze level culling so you can observe how much of the level is being rendered");
|
||||
consvar_t cv_debugrender_portal = PlayerCheat("debugrender_portal", "Off").on_off().description("Highlight visual portals in red");
|
||||
consvar_t cv_debugrender_spriteclip = PlayerCheat("debugrender_spriteclip", "Off").on_off().description("Let sprites draw through walls");
|
||||
consvar_t cv_debugrender_visplanes = PlayerCheat("debugrender_visplanes", "Off").on_off().description("Highlight the number of visplanes");
|
||||
consvar_t cv_devmode_screen = PlayerCheat("devmode_screen", "1").min_max(1, 4).description("Choose which splitscreen player devmode applies to");
|
||||
consvar_t cv_drawpickups = PlayerCheat("drawpickups", "Yes").yes_no().description("Hide rings, spheres, item capsules, prison capsules (visual only)");
|
||||
consvar_t cv_drawinput = PlayerCheat("drawinput", "No").yes_no().description("Draw turn inputs outside of Record Attack (turn solver debugging)");
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ CV_PossibleValue_t kartdebugitem_cons_t[] =
|
|||
{POWERUP_BUMPER, "Bumper"},
|
||||
{POWERUP_BADGE, "Badge"},
|
||||
{POWERUP_SUPERFLICKY, "SuperFlicky"},
|
||||
{POWERUP_POINTS, "Points"},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ typedef enum
|
|||
POWERUP_BUMPER,
|
||||
POWERUP_BADGE,
|
||||
POWERUP_SUPERFLICKY,
|
||||
POWERUP_POINTS,
|
||||
ENDOFPOWERUPS,
|
||||
LASTPOWERUP = ENDOFPOWERUPS - 1,
|
||||
NUMPOWERUPS = ENDOFPOWERUPS - FIRSTPOWERUP,
|
||||
|
|
|
|||
|
|
@ -2259,19 +2259,6 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_POWERCLASH", // Invinc/Grow no damage collide VFX
|
||||
"S_GUARDBREAK", // Guard break
|
||||
|
||||
"S_PLAYERARROW", // Above player arrow
|
||||
"S_PLAYERARROW_BOX",
|
||||
"S_PLAYERARROW_ITEM",
|
||||
"S_PLAYERARROW_NUMBER",
|
||||
"S_PLAYERARROW_X",
|
||||
"S_PLAYERARROW_WANTED1",
|
||||
"S_PLAYERARROW_WANTED2",
|
||||
"S_PLAYERARROW_WANTED3",
|
||||
"S_PLAYERARROW_WANTED4",
|
||||
"S_PLAYERARROW_WANTED5",
|
||||
"S_PLAYERARROW_WANTED6",
|
||||
"S_PLAYERARROW_WANTED7",
|
||||
|
||||
"S_PLAYERBOMB1", // Player bomb overlay
|
||||
"S_PLAYERBOMB2",
|
||||
"S_PLAYERBOMB3",
|
||||
|
|
@ -3615,9 +3602,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
|||
"MT_POWERCLASH", // Invinc/Grow no damage clash VFX
|
||||
"MT_GUARDBREAK", // Guard break
|
||||
|
||||
"MT_PLAYERARROW",
|
||||
"MT_PLAYERWANTED",
|
||||
|
||||
"MT_KARMAHITBOX",
|
||||
"MT_KARMAWHEEL",
|
||||
|
||||
|
|
@ -5057,6 +5041,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"POWERUP_BUMPER",POWERUP_BUMPER},
|
||||
{"POWERUP_BADGE",POWERUP_BADGE},
|
||||
{"POWERUP_SUPERFLICKY",POWERUP_SUPERFLICKY},
|
||||
{"POWERUP_POINTS",POWERUP_POINTS},
|
||||
{"ENDOFPOWERUPS",ENDOFPOWERUPS},
|
||||
{"LASTPOWERUP",LASTPOWERUP},
|
||||
{"NUMPOWERUPS",NUMPOWERUPS},
|
||||
|
|
|
|||
70
src/info.c
70
src/info.c
|
|
@ -472,14 +472,12 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"PWCL", // Invinc/grow clash VFX
|
||||
"GBRK", // Guard break
|
||||
|
||||
"ARRO", // player arrows
|
||||
"ITEM",
|
||||
"ITMO",
|
||||
"ITMI",
|
||||
"ITMN",
|
||||
"PWRB",
|
||||
"RBOW", // power-up aura
|
||||
"WANT",
|
||||
|
||||
"PBOM", // player bomb
|
||||
|
||||
|
|
@ -2744,20 +2742,6 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PWCL, FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE, 10, {NULL}, 9, 1, S_NULL}, // S_POWERCLASH
|
||||
{SPR_GBRK, FF_ADD|FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE, 24, {NULL}, 5, 4, S_NULL}, // S_GUARDBREAK
|
||||
|
||||
// Above player arrow
|
||||
{SPR_ARRO, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW
|
||||
{SPR_ARRO, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOX
|
||||
{SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 11, S_NULL}, // S_PLAYERARROW_ITEM
|
||||
{SPR_ITMN, FF_FULLBRIGHT, 2, {NULL}, 0, 11, S_NULL}, // S_PLAYERARROW_NUMBER
|
||||
{SPR_ITMN, FF_FULLBRIGHT|11, 2, {NULL}, 0, 11, S_NULL}, // S_PLAYERARROW_X
|
||||
{SPR_WANT, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_PLAYERARROW_WANTED2}, // S_PLAYERARROW_WANTED1
|
||||
{SPR_WANT, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED3}, // S_PLAYERARROW_WANTED2
|
||||
{SPR_WANT, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED4}, // S_PLAYERARROW_WANTED3
|
||||
{SPR_WANT, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED5}, // S_PLAYERARROW_WANTED4
|
||||
{SPR_WANT, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED6}, // S_PLAYERARROW_WANTED5
|
||||
{SPR_WANT, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED7}, // S_PLAYERARROW_WANTED6
|
||||
{SPR_WANT, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED1}, // S_PLAYERARROW_WANTED7
|
||||
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_PLAYERBOMB2}, // S_PLAYERBOMB1
|
||||
{SPR_SPBM, 1, 1, {NULL}, 0, 0, S_PLAYERBOMB3}, // S_PLAYERBOMB2
|
||||
{SPR_SPBM, 0, 1, {NULL}, 0, 0, S_PLAYERBOMB4}, // S_PLAYERBOMB3
|
||||
|
|
@ -16422,60 +16406,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_PLAYERARROW
|
||||
-1, // doomednum
|
||||
S_PLAYERARROW, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
8, // speed
|
||||
36*FRACUNIT, // radius
|
||||
37*FRACUNIT, // height
|
||||
-2, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_PLAYERWANTED
|
||||
-1, // doomednum
|
||||
S_PLAYERARROW_WANTED1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
8, // speed
|
||||
36*FRACUNIT, // radius
|
||||
37*FRACUNIT, // height
|
||||
-2, // display offset
|
||||
16, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_KARMAHITBOX
|
||||
-1, // doomednum
|
||||
S_PLAYERBOMB1, // spawnstate
|
||||
|
|
|
|||
18
src/info.h
18
src/info.h
|
|
@ -1011,14 +1011,12 @@ typedef enum sprite
|
|||
SPR_PWCL, // Invinc/grow clash VFX
|
||||
SPR_GBRK, // Guard break
|
||||
|
||||
SPR_ARRO, // player arrows
|
||||
SPR_ITEM,
|
||||
SPR_ITMO,
|
||||
SPR_ITMI,
|
||||
SPR_ITMN,
|
||||
SPR_PWRB,
|
||||
SPR_RBOW, // power-up aura
|
||||
SPR_WANT,
|
||||
|
||||
SPR_PBOM, // player bomb
|
||||
|
||||
|
|
@ -3250,19 +3248,6 @@ typedef enum state
|
|||
S_POWERCLASH, // Grow/Invinc clash VFX
|
||||
S_GUARDBREAK,
|
||||
|
||||
S_PLAYERARROW, // Above player arrow
|
||||
S_PLAYERARROW_BOX,
|
||||
S_PLAYERARROW_ITEM,
|
||||
S_PLAYERARROW_NUMBER,
|
||||
S_PLAYERARROW_X,
|
||||
S_PLAYERARROW_WANTED1,
|
||||
S_PLAYERARROW_WANTED2,
|
||||
S_PLAYERARROW_WANTED3,
|
||||
S_PLAYERARROW_WANTED4,
|
||||
S_PLAYERARROW_WANTED5,
|
||||
S_PLAYERARROW_WANTED6,
|
||||
S_PLAYERARROW_WANTED7,
|
||||
|
||||
S_PLAYERBOMB1, // Karma player overlays
|
||||
S_PLAYERBOMB2,
|
||||
S_PLAYERBOMB3,
|
||||
|
|
@ -4633,9 +4618,6 @@ typedef enum mobj_type
|
|||
MT_POWERCLASH, // Grow/Invinc clash VFX
|
||||
MT_GUARDBREAK,
|
||||
|
||||
MT_PLAYERARROW,
|
||||
MT_PLAYERWANTED,
|
||||
|
||||
MT_KARMAHITBOX,
|
||||
MT_KARMAWHEEL,
|
||||
|
||||
|
|
|
|||
|
|
@ -173,14 +173,9 @@ void K_CheckBumpers(void)
|
|||
}
|
||||
else if (eliminated >= numingame - 1)
|
||||
{
|
||||
if (kingofthehill != -1)
|
||||
{
|
||||
// If every other player is eliminated, the
|
||||
// last player standing wins by default.
|
||||
players[kingofthehill].roundscore = 100;
|
||||
}
|
||||
|
||||
P_DoAllPlayersExit(0, false);
|
||||
// If every other player is eliminated, the
|
||||
// last player standing wins by default.
|
||||
K_EndBattleRound(kingofthehill != -1 ? &players[kingofthehill] : NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -209,15 +204,11 @@ void K_CheckEmeralds(player_t *player)
|
|||
return;
|
||||
}
|
||||
|
||||
if (player->exiting)
|
||||
if (!K_EndBattleRound(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player->roundscore = 100; // lmao
|
||||
|
||||
P_DoAllPlayersExit(0, false);
|
||||
|
||||
// TODO: this would be better if the timing lived in
|
||||
// Tally code. But I didn't do it that, so this just
|
||||
// shittily approximates syncing up with Tally.
|
||||
|
|
@ -969,3 +960,27 @@ boolean K_BattleOvertimeKiller(mobj_t *mobj)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean K_EndBattleRound(player_t *victor)
|
||||
{
|
||||
if (victor)
|
||||
{
|
||||
if (victor->exiting)
|
||||
{
|
||||
// In Battle, players always exit altogether.
|
||||
// So it can be assumed that if this player is
|
||||
// exiting, the round has already ended.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gametyperules & GTR_POINTLIMIT)
|
||||
{
|
||||
// Lock the winner in before the round ends.
|
||||
victor->roundscore = 100;
|
||||
}
|
||||
}
|
||||
|
||||
P_DoAllPlayersExit(0, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ void K_BattleInit(boolean singleplayercontext);
|
|||
UINT8 K_Bumpers(player_t *player);
|
||||
INT32 K_BumpersToHealth(UINT8 bumpers);
|
||||
boolean K_BattleOvertimeKiller(mobj_t *mobj);
|
||||
boolean K_EndBattleRound(player_t *victor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ struct Camera : camera_t
|
|||
struct EndCam : endcam_t
|
||||
{
|
||||
tic_t Time() const { return leveltime - begin; }
|
||||
bool Freezing() const { return Time() <= swirlDuration; }
|
||||
bool Freezing() const { return active && Time() <= swirlDuration; }
|
||||
|
||||
void GC()
|
||||
{
|
||||
|
|
|
|||
383
src/k_hud.cpp
383
src/k_hud.cpp
|
|
@ -130,36 +130,36 @@ static patch_t *kp_wantedsplit;
|
|||
static patch_t *kp_wantedreticle;
|
||||
static patch_t *kp_minimapdot;
|
||||
|
||||
static patch_t *kp_itembg[4];
|
||||
static patch_t *kp_itembg[6];
|
||||
static patch_t *kp_ringbg[4];
|
||||
static patch_t *kp_itemtimer[2];
|
||||
static patch_t *kp_itemmulsticker[2];
|
||||
static patch_t *kp_itemx;
|
||||
|
||||
static patch_t *kp_sadface[2];
|
||||
static patch_t *kp_sneaker[2];
|
||||
static patch_t *kp_rocketsneaker[2];
|
||||
static patch_t *kp_invincibility[13];
|
||||
static patch_t *kp_banana[2];
|
||||
static patch_t *kp_eggman[2];
|
||||
static patch_t *kp_orbinaut[5];
|
||||
static patch_t *kp_jawz[2];
|
||||
static patch_t *kp_mine[2];
|
||||
static patch_t *kp_landmine[2];
|
||||
static patch_t *kp_ballhog[2];
|
||||
static patch_t *kp_selfpropelledbomb[2];
|
||||
static patch_t *kp_grow[2];
|
||||
static patch_t *kp_shrink[2];
|
||||
static patch_t *kp_lightningshield[2];
|
||||
static patch_t *kp_bubbleshield[2];
|
||||
static patch_t *kp_flameshield[2];
|
||||
static patch_t *kp_hyudoro[2];
|
||||
static patch_t *kp_pogospring[2];
|
||||
static patch_t *kp_superring[2];
|
||||
static patch_t *kp_kitchensink[2];
|
||||
static patch_t *kp_droptarget[2];
|
||||
static patch_t *kp_gardentop[2];
|
||||
static patch_t *kp_gachabom[2];
|
||||
static patch_t *kp_sadface[3];
|
||||
static patch_t *kp_sneaker[3];
|
||||
static patch_t *kp_rocketsneaker[3];
|
||||
static patch_t *kp_invincibility[19];
|
||||
static patch_t *kp_banana[3];
|
||||
static patch_t *kp_eggman[3];
|
||||
static patch_t *kp_orbinaut[6];
|
||||
static patch_t *kp_jawz[3];
|
||||
static patch_t *kp_mine[3];
|
||||
static patch_t *kp_landmine[3];
|
||||
static patch_t *kp_ballhog[3];
|
||||
static patch_t *kp_selfpropelledbomb[3];
|
||||
static patch_t *kp_grow[3];
|
||||
static patch_t *kp_shrink[3];
|
||||
static patch_t *kp_lightningshield[3];
|
||||
static patch_t *kp_bubbleshield[3];
|
||||
static patch_t *kp_flameshield[3];
|
||||
static patch_t *kp_hyudoro[3];
|
||||
static patch_t *kp_pogospring[3];
|
||||
static patch_t *kp_superring[3];
|
||||
static patch_t *kp_kitchensink[3];
|
||||
static patch_t *kp_droptarget[3];
|
||||
static patch_t *kp_gardentop[3];
|
||||
static patch_t *kp_gachabom[3];
|
||||
static patch_t *kp_bar[2];
|
||||
static patch_t *kp_doublebar[2];
|
||||
static patch_t *kp_triplebar[2];
|
||||
|
|
@ -613,6 +613,40 @@ void K_LoadKartHUDGraphics(void)
|
|||
HU_UpdatePatch(&kp_flameshieldmeter_bg[i][1], "%s", buffer);
|
||||
}
|
||||
|
||||
// 4P item spy
|
||||
HU_UpdatePatch(&kp_itembg[4], "ISPYBG");
|
||||
HU_UpdatePatch(&kp_itembg[5], "ISPYBGD");
|
||||
|
||||
//HU_UpdatePatch(&kp_sadface[2], "ISPYSAD");
|
||||
HU_UpdatePatch(&kp_sneaker[2], "ISPYSHOE");
|
||||
HU_UpdatePatch(&kp_rocketsneaker[2], "ISPYRSHE");
|
||||
sprintf(buffer, "ISPYINVx");
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
buffer[7] = '1'+i;
|
||||
HU_UpdatePatch(&kp_invincibility[i+13], "%s", buffer);
|
||||
}
|
||||
HU_UpdatePatch(&kp_banana[2], "ISPYBANA");
|
||||
HU_UpdatePatch(&kp_eggman[2], "ISPYEGGM");
|
||||
HU_UpdatePatch(&kp_orbinaut[5], "ISPYORBN");
|
||||
HU_UpdatePatch(&kp_jawz[2], "ISPYJAWZ");
|
||||
HU_UpdatePatch(&kp_mine[2], "ISPYMINE");
|
||||
HU_UpdatePatch(&kp_landmine[2], "ISPYLNDM");
|
||||
HU_UpdatePatch(&kp_ballhog[2], "ISPYBHOG");
|
||||
HU_UpdatePatch(&kp_selfpropelledbomb[2], "ISPYSPB");
|
||||
HU_UpdatePatch(&kp_grow[2], "ISPYGROW");
|
||||
HU_UpdatePatch(&kp_shrink[2], "ISPYSHRK");
|
||||
HU_UpdatePatch(&kp_lightningshield[2], "ISPYTHNS");
|
||||
HU_UpdatePatch(&kp_bubbleshield[2], "ISPYBUBS");
|
||||
HU_UpdatePatch(&kp_flameshield[2], "ISPYFLMS");
|
||||
HU_UpdatePatch(&kp_hyudoro[2], "ISPYHYUD");
|
||||
HU_UpdatePatch(&kp_pogospring[2], "ISPYPOGO");
|
||||
HU_UpdatePatch(&kp_superring[2], "ISPYRING");
|
||||
HU_UpdatePatch(&kp_kitchensink[2], "ISPYSINK");
|
||||
HU_UpdatePatch(&kp_droptarget[2], "ISPYDTRG");
|
||||
HU_UpdatePatch(&kp_gardentop[2], "ISPYGTOP");
|
||||
HU_UpdatePatch(&kp_gachabom[2], "ISPYGBOM");
|
||||
|
||||
// CHECK indicators
|
||||
sprintf(buffer, "K_CHECKx");
|
||||
for (i = 0; i < 6; i++)
|
||||
|
|
@ -1325,7 +1359,7 @@ void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, p
|
|||
);
|
||||
}
|
||||
|
||||
// see also MT_PLAYERARROW mobjthinker in p_mobj.c
|
||||
// see also K_DrawNameTagItemSpy
|
||||
static void K_drawKartItem(void)
|
||||
{
|
||||
// ITEM_X = BASEVIDWIDTH-50; // 270
|
||||
|
|
@ -3207,6 +3241,7 @@ static void K_drawKartSpeedometer(boolean gametypeinfoshown)
|
|||
static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
|
||||
{
|
||||
const UINT8 maxBars = 4;
|
||||
// see also K_DrawNameTagSphereMeter
|
||||
const UINT8 segColors[] = {73, 64, 52, 54, 55, 35, 34, 33, 202, 180, 181, 182, 164, 165, 166, 153, 152};
|
||||
const UINT8 sphere = std::clamp(static_cast<int>(stplyr->spheres), 0, 40);
|
||||
|
||||
|
|
@ -3675,28 +3710,101 @@ static void K_DrawRivalTagForPlayer(fixed_t x, fixed_t y)
|
|||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_rival[blink], NULL);
|
||||
}
|
||||
|
||||
static void K_DrawTypingDot(fixed_t x, fixed_t y, UINT8 duration, player_t *p)
|
||||
static void K_DrawTypingDot(fixed_t x, fixed_t y, UINT8 duration, player_t *p, INT32 flags)
|
||||
{
|
||||
if (p->typing_duration > duration)
|
||||
{
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_typdot, NULL);
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN|flags, kp_typdot, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_DrawTypingNotifier(fixed_t x, fixed_t y, player_t *p)
|
||||
static void K_DrawTypingNotifier(fixed_t x, fixed_t y, player_t *p, INT32 flags)
|
||||
{
|
||||
if (p->cmd.flags & TICCMD_TYPING)
|
||||
{
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_talk, NULL);
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN|flags, kp_talk, NULL);
|
||||
|
||||
/* spacing closer with the last two looks a better most of the time */
|
||||
K_DrawTypingDot(x + 3*FRACUNIT, y, 15, p);
|
||||
K_DrawTypingDot(x + 6*FRACUNIT - FRACUNIT/3, y, 31, p);
|
||||
K_DrawTypingDot(x + 9*FRACUNIT - FRACUNIT/3, y, 47, p);
|
||||
K_DrawTypingDot(x + 3*FRACUNIT, y, 15, p, flags);
|
||||
K_DrawTypingDot(x + 6*FRACUNIT - FRACUNIT/3, y, 31, p, flags);
|
||||
K_DrawTypingDot(x + 9*FRACUNIT - FRACUNIT/3, y, 47, p, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p)
|
||||
// see also K_drawKartItem
|
||||
static void K_DrawNameTagItemSpy(INT32 x, INT32 y, player_t *p, INT32 flags)
|
||||
{
|
||||
using srb2::Draw;
|
||||
bool tiny = r_splitscreen > 1;
|
||||
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);
|
||||
|
||||
box.colorize(p->skincolor).patch(kp_itembg[tiny ? 4 : 2]);
|
||||
|
||||
if (!(p->itemflags & IF_ITEMOUT) || (leveltime & 1))
|
||||
{
|
||||
switch (p->itemtype)
|
||||
{
|
||||
case KITEM_INVINCIBILITY:
|
||||
box.patch(kp_invincibility[((leveltime % (6*3)) / 3) + (tiny ? 13 : 7)]);
|
||||
break;
|
||||
|
||||
case KITEM_ORBINAUT:
|
||||
box.patch(kp_orbinaut[4 + tiny]);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (patch_t *ico = K_GetCachedItemPatch(p->itemtype, 1 + tiny))
|
||||
{
|
||||
box.patch(ico);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p->itemamount > 1)
|
||||
{
|
||||
(tiny ?
|
||||
bar.xy(-3 * vid.dupx, -4 * vid.dupy).font(Draw::Font::kPing) :
|
||||
bar.xy(-4 * vid.dupx, -2 * vid.dupy).font(Draw::Font::kThinTimer)
|
||||
)
|
||||
.align(Draw::Align::kRight)
|
||||
.text("{}", p->itemamount);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_DrawNameTagSphereMeter(INT32 x, INT32 y, INT32 width, INT32 spheres, INT32 flags)
|
||||
{
|
||||
using srb2::Draw;
|
||||
Draw bar = Draw(x + vid.dupx, y).flags(V_NOSCALESTART).height(vid.dupy);
|
||||
|
||||
// see also K_drawBlueSphereMeter
|
||||
const UINT8 segColors[] = {73, 64, 52, 54, 55, 35, 34, 33, 202, 180, 181, 182, 164, 165, 166, 153, 152};
|
||||
|
||||
spheres = std::clamp(spheres, 0, 40);
|
||||
int colorIndex = (spheres * sizeof segColors) / (40 + 1);
|
||||
|
||||
int px = r_splitscreen > 1 ? 1 : 2;
|
||||
int b = 10 * px;
|
||||
int m = spheres * px;
|
||||
|
||||
while (m > 0)
|
||||
{
|
||||
if (b > m)
|
||||
b = m;
|
||||
|
||||
Draw seg = bar.width(b);
|
||||
|
||||
seg.fill(segColors[std::max(colorIndex - 1, 0)]);
|
||||
seg.y(vid.dupy).fill(segColors[std::max(colorIndex - 2, 0)]);
|
||||
seg.y(2 * vid.dupy).height(2 * vid.dupy).fill(segColors[colorIndex]);
|
||||
seg.y(4 * vid.dupy).fill(31);
|
||||
|
||||
bar = bar.x(b + vid.dupx);
|
||||
m -= b;
|
||||
}
|
||||
}
|
||||
|
||||
static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p, INT32 flags)
|
||||
{
|
||||
const INT32 clr = skincolors[p->skincolor].chatcolor;
|
||||
const INT32 namelen = V_ThinStringWidth(player_names[p - players], 0);
|
||||
|
|
@ -3738,16 +3846,76 @@ static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p)
|
|||
bary += (vid.height - (BASEVIDHEIGHT * vid.dupy)) / 2;
|
||||
}
|
||||
|
||||
// see also K_CullTargetList
|
||||
if ((gametyperules & GTR_ITEMARROWS) && p->itemtype != KITEM_NONE && p->itemamount != 0)
|
||||
{
|
||||
K_DrawNameTagItemSpy(barx, bary, p, flags);
|
||||
}
|
||||
|
||||
if (gametyperules & GTR_SPHERES)
|
||||
{
|
||||
K_DrawNameTagSphereMeter(barx, bary + (4 * vid.dupy), 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.
|
||||
V_DrawFill(barx, bary, barw, (3 * vid.dupy), (colormap ? colormap[31] : 31)|V_NOSCALESTART);
|
||||
V_DrawFill(barx, bary + vid.dupy, barw, vid.dupy, (colormap ? colormap[0] : 0)|V_NOSCALESTART);
|
||||
V_DrawFill(barx, bary, barw, (3 * vid.dupy), (colormap ? colormap[31] : 31)|V_NOSCALESTART|flags);
|
||||
V_DrawFill(barx, bary + vid.dupy, barw, vid.dupy, (colormap ? colormap[0] : 0)|V_NOSCALESTART|flags);
|
||||
// END DRAWFILL DUMBNESS
|
||||
|
||||
// Draw the stem
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, 0, kp_nametagstem, colormap);
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, flags, kp_nametagstem, colormap);
|
||||
|
||||
// Draw the name itself
|
||||
V_DrawThinStringAtFixed(x + (5*FRACUNIT), y - (26*FRACUNIT), clr, player_names[p - players]);
|
||||
V_DrawThinStringAtFixed(x + (5*FRACUNIT), y - (26*FRACUNIT), clr|flags, player_names[p - players]);
|
||||
}
|
||||
|
||||
playertagtype_t K_WhichPlayerTag(player_t *p)
|
||||
{
|
||||
UINT8 cnum = R_GetViewNumber();
|
||||
|
||||
if (!(demo.playback == true && camera[cnum].freecam == true) && P_IsDisplayPlayer(p) &&
|
||||
p != &players[displayplayers[cnum]])
|
||||
{
|
||||
return PLAYERTAG_LOCAL;
|
||||
}
|
||||
else if (p->bot)
|
||||
{
|
||||
if (p->botvars.rival == true)
|
||||
{
|
||||
return PLAYERTAG_RIVAL;
|
||||
}
|
||||
}
|
||||
else if (netgame || demo.playback)
|
||||
{
|
||||
if (K_ShowPlayerNametag(p) == true)
|
||||
{
|
||||
return PLAYERTAG_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
return PLAYERTAG_NONE;
|
||||
}
|
||||
|
||||
void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type, INT32 flags)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLAYERTAG_LOCAL:
|
||||
K_DrawLocalTagForPlayer(x, y, p, G_PartyPosition(p - players));
|
||||
break;
|
||||
|
||||
case PLAYERTAG_RIVAL:
|
||||
K_DrawRivalTagForPlayer(x, y);
|
||||
break;
|
||||
|
||||
case PLAYERTAG_NAME:
|
||||
K_DrawNameTagForPlayer(x, y, p, flags);
|
||||
K_DrawTypingNotifier(x, y, p, flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct weakspotdraw_t
|
||||
|
|
@ -3789,12 +3957,8 @@ static void K_DrawWeakSpot(weakspotdraw_t *ws)
|
|||
|
||||
static void K_drawKartNameTags(void)
|
||||
{
|
||||
const fixed_t maxdistance = 8192*mapobjectscale;
|
||||
vector3_t c;
|
||||
UINT8 cnum = R_GetViewNumber();
|
||||
UINT8 tobesorted[MAXPLAYERS];
|
||||
fixed_t sortdist[MAXPLAYERS];
|
||||
UINT8 sortlen = 0;
|
||||
size_t i, j;
|
||||
|
||||
if (stplyr == NULL || stplyr->mo == NULL || P_MobjWasRemoved(stplyr->mo))
|
||||
|
|
@ -3913,141 +4077,6 @@ static void K_drawKartNameTags(void)
|
|||
|
||||
K_drawTargetHUD(&c, stplyr);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *ntplayer = &players[i];
|
||||
fixed_t distance = maxdistance+1;
|
||||
vector3_t v;
|
||||
|
||||
if (!playeringame[i] || ntplayer->spectator)
|
||||
{
|
||||
// Not in-game
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ntplayer->mo == NULL || P_MobjWasRemoved(ntplayer->mo))
|
||||
{
|
||||
// No object
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ntplayer->mo->renderflags & K_GetPlayerDontDrawFlag(stplyr))
|
||||
{
|
||||
// Invisible on this screen
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!P_CheckSight(stplyr->mo, ntplayer->mo))
|
||||
{
|
||||
// Can't see
|
||||
continue;
|
||||
}
|
||||
|
||||
v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x);
|
||||
v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y);
|
||||
v.z = R_InterpolateFixed(ntplayer->mo->old_z, ntplayer->mo->z);
|
||||
|
||||
if (!(ntplayer->mo->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
v.z += ntplayer->mo->height;
|
||||
}
|
||||
|
||||
distance = R_PointToDist2(c.x, c.y, v.x, v.y);
|
||||
|
||||
if (distance > maxdistance)
|
||||
{
|
||||
// Too far away
|
||||
continue;
|
||||
}
|
||||
|
||||
tobesorted[sortlen] = ntplayer - players;
|
||||
sortdist[sortlen] = distance;
|
||||
sortlen++;
|
||||
}
|
||||
|
||||
if (sortlen > 0)
|
||||
{
|
||||
UINT8 sortedplayers[MAXPLAYERS];
|
||||
|
||||
for (i = 0; i < sortlen; i++)
|
||||
{
|
||||
UINT8 pos = 0;
|
||||
|
||||
for (j = 0; j < sortlen; j++)
|
||||
{
|
||||
if (j == i)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sortdist[i] < sortdist[j]
|
||||
|| (sortdist[i] == sortdist[j] && i > j))
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
sortedplayers[pos] = tobesorted[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < sortlen; i++)
|
||||
{
|
||||
trackingResult_t result;
|
||||
player_t *ntplayer = &players[sortedplayers[i]];
|
||||
|
||||
fixed_t headOffset = 36*ntplayer->mo->scale;
|
||||
|
||||
SINT8 localindicator = -1;
|
||||
vector3_t v;
|
||||
|
||||
v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x);
|
||||
v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y);
|
||||
v.z = R_InterpolateFixed(ntplayer->mo->old_z, ntplayer->mo->z);
|
||||
|
||||
v.z += (ntplayer->mo->height / 2);
|
||||
|
||||
if (stplyr->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
v.z -= headOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
v.z += headOffset;
|
||||
}
|
||||
|
||||
K_ObjectTracking(&result, &v, false);
|
||||
|
||||
if (result.onScreen == true)
|
||||
{
|
||||
if (!(demo.playback == true && camera[cnum].freecam == true) && P_IsDisplayPlayer(ntplayer) &&
|
||||
ntplayer != &players[displayplayers[cnum]])
|
||||
{
|
||||
localindicator = G_PartyPosition(ntplayer - players);
|
||||
}
|
||||
|
||||
if (localindicator >= 0)
|
||||
{
|
||||
K_DrawLocalTagForPlayer(result.x, result.y, ntplayer, localindicator);
|
||||
}
|
||||
else if (ntplayer->bot)
|
||||
{
|
||||
if (ntplayer->botvars.rival == true)
|
||||
{
|
||||
K_DrawRivalTagForPlayer(result.x, result.y);
|
||||
}
|
||||
}
|
||||
else if (netgame || demo.playback)
|
||||
{
|
||||
if (K_ShowPlayerNametag(ntplayer) == true)
|
||||
{
|
||||
K_DrawNameTagForPlayer(result.x, result.y, ntplayer);
|
||||
K_DrawTypingNotifier(result.x, result.y, ntplayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
V_ClearClipRect();
|
||||
}
|
||||
|
||||
|
|
|
|||
12
src/k_hud.h
12
src/k_hud.h
|
|
@ -99,6 +99,18 @@ void K_ClearPersistentMessages(void);
|
|||
void K_ClearPersistentMessageForPlayer(player_t *player);
|
||||
void K_TickMessages(void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PLAYERTAG_NONE,
|
||||
PLAYERTAG_LOCAL,
|
||||
PLAYERTAG_RIVAL,
|
||||
PLAYERTAG_NAME,
|
||||
}
|
||||
playertagtype_t;
|
||||
|
||||
playertagtype_t K_WhichPlayerTag(player_t *p);
|
||||
void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type, INT32 flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "core/static_vec.hpp"
|
||||
#include "v_draw.hpp"
|
||||
|
||||
#include "g_game.h"
|
||||
#include "k_battle.h"
|
||||
#include "k_hud.h"
|
||||
#include "k_kart.h"
|
||||
|
|
@ -67,6 +68,7 @@ struct TargetTracking
|
|||
trackingResult_t result;
|
||||
fixed_t camDist;
|
||||
bool foreground;
|
||||
playertagtype_t nametag;
|
||||
|
||||
skincolornum_t color() const
|
||||
{
|
||||
|
|
@ -165,6 +167,42 @@ struct TargetTracking
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool is_player_nametag_on_screen() const
|
||||
{
|
||||
const player_t* player = mobj->player;
|
||||
|
||||
if (nametag == PLAYERTAG_NONE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player->spectator)
|
||||
{
|
||||
// Not in-game
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mobj->renderflags & K_GetPlayerDontDrawFlag(stplyr))
|
||||
{
|
||||
// Invisible on this screen
|
||||
return false;
|
||||
}
|
||||
|
||||
if (camDist > 8192*mapobjectscale)
|
||||
{
|
||||
// Too far away
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!P_CheckSight(stplyr->mo, const_cast<mobj_t*>(mobj)))
|
||||
{
|
||||
// Can't see
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Graphics graphics() const
|
||||
{
|
||||
|
|
@ -320,6 +358,12 @@ Visibility is_object_visible(const mobj_t* mobj)
|
|||
|
||||
void K_DrawTargetTracking(const TargetTracking& target)
|
||||
{
|
||||
if (target.nametag != PLAYERTAG_NONE)
|
||||
{
|
||||
K_DrawPlayerTag(target.result.x, target.result.y, target.mobj->player, target.nametag, target.foreground ? 0 : V_60TRANS);
|
||||
return;
|
||||
}
|
||||
|
||||
Visibility visibility = is_object_visible(target.mobj);
|
||||
|
||||
if (visibility == Visibility::kFlicker && (leveltime & 1))
|
||||
|
|
@ -524,6 +568,7 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
|||
{
|
||||
using srb2::Draw;
|
||||
Draw(FixedToFloat(result.x), FixedToFloat(result.y))
|
||||
.flags(V_SPLITSCREEN)
|
||||
.font(Draw::Font::kThin)
|
||||
.align(Draw::Align::kCenter)
|
||||
.text("BUFO ID: {}", Obj_BattleUFOSpawnerID(target.mobj));
|
||||
|
|
@ -533,10 +578,11 @@ void K_DrawTargetTracking(const TargetTracking& target)
|
|||
|
||||
void K_CullTargetList(std::vector<TargetTracking>& targetList)
|
||||
{
|
||||
constexpr int kBlockSize = 20;
|
||||
constexpr int kXBlocks = BASEVIDWIDTH / kBlockSize;
|
||||
constexpr int kYBlocks = BASEVIDHEIGHT / kBlockSize;
|
||||
bool map[kXBlocks][kYBlocks] = {};
|
||||
constexpr int kBlockWidth = 20;
|
||||
constexpr int kBlockHeight = 10;
|
||||
constexpr int kXBlocks = BASEVIDWIDTH / kBlockWidth;
|
||||
constexpr int kYBlocks = BASEVIDHEIGHT / kBlockHeight;
|
||||
UINT8 map[kXBlocks][kYBlocks] = {};
|
||||
|
||||
constexpr fixed_t kTrackerRadius = 30*FRACUNIT/2; // just an approximation of common HUD tracker
|
||||
|
||||
|
|
@ -552,10 +598,43 @@ void K_CullTargetList(std::vector<TargetTracking>& targetList)
|
|||
return;
|
||||
}
|
||||
|
||||
fixed_t x1 = std::max(((tr.result.x - kTrackerRadius) / kBlockSize) / FRACUNIT, 0);
|
||||
fixed_t x2 = std::min(((tr.result.x + kTrackerRadius) / kBlockSize) / FRACUNIT, kXBlocks - 1);
|
||||
fixed_t y1 = std::max(((tr.result.y - kTrackerRadius) / kBlockSize) / FRACUNIT, 0);
|
||||
fixed_t y2 = std::min(((tr.result.y + kTrackerRadius) / kBlockSize) / FRACUNIT, kYBlocks - 1);
|
||||
fixed_t x1, x2, y1, y2;
|
||||
UINT8 bit = 1;
|
||||
|
||||
// TODO: there should be some generic system
|
||||
// instead of this special case.
|
||||
if (tr.nametag == PLAYERTAG_NAME)
|
||||
{
|
||||
const player_t* p = tr.mobj->player;
|
||||
|
||||
x1 = tr.result.x;
|
||||
x2 = tr.result.x + ((6 + V_ThinStringWidth(player_names[p - players], 0)) * FRACUNIT);
|
||||
y1 = tr.result.y - (30 * FRACUNIT);
|
||||
y2 = tr.result.y - (4 * FRACUNIT);
|
||||
bit = 2; // nametags will cull on a separate plane
|
||||
|
||||
// see also K_DrawNameTagForPlayer
|
||||
if ((gametyperules & GTR_ITEMARROWS) && p->itemtype != KITEM_NONE && p->itemamount != 0)
|
||||
{
|
||||
x1 -= 24 * FRACUNIT;
|
||||
}
|
||||
}
|
||||
else if (tr.nametag != PLAYERTAG_NONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = tr.result.x - kTrackerRadius;
|
||||
x2 = tr.result.x + kTrackerRadius;
|
||||
y1 = tr.result.y - kTrackerRadius;
|
||||
y2 = tr.result.y + kTrackerRadius;
|
||||
}
|
||||
|
||||
x1 = std::max(x1 / kBlockWidth / FRACUNIT, 0);
|
||||
x2 = std::min(x2 / kBlockWidth / FRACUNIT, kXBlocks - 1);
|
||||
y1 = std::max(y1 / kBlockHeight / FRACUNIT, 0);
|
||||
y2 = std::min(y2 / kBlockHeight / FRACUNIT, kYBlocks - 1);
|
||||
|
||||
bool allMine = true;
|
||||
|
||||
|
|
@ -563,17 +642,23 @@ void K_CullTargetList(std::vector<TargetTracking>& targetList)
|
|||
{
|
||||
for (fixed_t y = y1; y <= y2; ++y)
|
||||
{
|
||||
if (map[x][y])
|
||||
if (map[x][y] & bit)
|
||||
{
|
||||
allMine = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[x][y] = true;
|
||||
map[x][y] |= bit;
|
||||
|
||||
if (cv_debughudtracker.value)
|
||||
{
|
||||
V_DrawFill(x * kBlockSize, y * kBlockSize, kBlockSize, kBlockSize, 39 + debugColorCycle);
|
||||
V_DrawFill(
|
||||
x * kBlockWidth,
|
||||
y * kBlockHeight,
|
||||
kBlockWidth,
|
||||
kBlockHeight,
|
||||
(39 + debugColorCycle) | V_SPLITSCREEN
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -611,7 +696,10 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (is_object_tracking_target(mobj) == false)
|
||||
bool tracking = is_object_tracking_target(mobj);
|
||||
playertagtype_t nametag = mobj->player ? K_WhichPlayerTag(mobj->player) : PLAYERTAG_NONE;
|
||||
|
||||
if (tracking == false && nametag == PLAYERTAG_NONE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -627,10 +715,39 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player)
|
|||
tr.mobj = mobj;
|
||||
tr.camDist = R_PointToDist2(origin->x, origin->y, pos.x, pos.y);
|
||||
tr.foreground = false;
|
||||
tr.nametag = PLAYERTAG_NONE;
|
||||
|
||||
K_ObjectTracking(&tr.result, &pos, false);
|
||||
if (tracking)
|
||||
{
|
||||
K_ObjectTracking(&tr.result, &pos, false);
|
||||
targetList.push_back(tr);
|
||||
}
|
||||
|
||||
targetList.push_back(tr);
|
||||
if (!mobj->player)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tr.nametag = nametag;
|
||||
|
||||
if (tr.is_player_nametag_on_screen())
|
||||
{
|
||||
fixed_t headOffset = 36*mobj->scale;
|
||||
if (stplyr->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
pos.z -= headOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.z += headOffset;
|
||||
}
|
||||
K_ObjectTracking(&tr.result, &pos, false);
|
||||
|
||||
if (tr.result.onScreen == true)
|
||||
{
|
||||
targetList.push_back(tr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by distance from camera. Further trackers get
|
||||
|
|
|
|||
20
src/k_kart.c
20
src/k_kart.c
|
|
@ -3897,6 +3897,12 @@ void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UIN
|
|||
return;
|
||||
}
|
||||
|
||||
if (player->exiting)
|
||||
{
|
||||
// The round has already ended, don't mess with points
|
||||
return;
|
||||
}
|
||||
|
||||
if ((inflictor && !P_MobjWasRemoved(inflictor)) && (inflictor->type == MT_BANANA && inflictor->health > 1))
|
||||
{
|
||||
trapItem = true;
|
||||
|
|
@ -3923,8 +3929,7 @@ void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UIN
|
|||
// Check this before adding to player score
|
||||
if ((gametyperules & GTR_BUMPERS) && finishOff && g_pointlimit <= player->roundscore)
|
||||
{
|
||||
player->roundscore = 100; // Make sure you win!
|
||||
P_DoAllPlayersExit(0, false);
|
||||
K_EndBattleRound(player);
|
||||
|
||||
mobj_t *source = !P_MobjWasRemoved(inflictor) ? inflictor : player->mo;
|
||||
|
||||
|
|
@ -3937,8 +3942,7 @@ void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UIN
|
|||
);
|
||||
}
|
||||
|
||||
P_AddPlayerScore(player, points);
|
||||
K_SpawnBattlePoints(player, victim, points);
|
||||
K_GivePointsToPlayer(player, victim, points);
|
||||
}
|
||||
|
||||
void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type)
|
||||
|
|
@ -4847,6 +4851,12 @@ void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount)
|
|||
S_StartSound(player->mo, sfx_3db06);
|
||||
}
|
||||
|
||||
void K_GivePointsToPlayer(player_t *player, player_t *victim, UINT8 amount)
|
||||
{
|
||||
P_AddPlayerScore(player, amount);
|
||||
K_SpawnBattlePoints(player, victim, amount);
|
||||
}
|
||||
|
||||
#define MINEQUAKEDIST 4096
|
||||
|
||||
// Does the proximity screen flash and quake for explosions
|
||||
|
|
@ -13422,7 +13432,7 @@ UINT32 K_PointLimitForGametype(void)
|
|||
{
|
||||
if (D_IsPlayerHumanAndGaming(i))
|
||||
{
|
||||
ptsCap += 4;
|
||||
ptsCap += 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
|||
void K_DebtStingPlayer(player_t *player, mobj_t *source);
|
||||
void K_GiveBumpersToPlayer(player_t *player, player_t *victim, UINT8 amount);
|
||||
void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount);
|
||||
void K_GivePointsToPlayer(player_t *player, player_t *victim, UINT8 amount);
|
||||
void K_MineFlashScreen(mobj_t *source);
|
||||
void K_SpawnMineExplosion(mobj_t *source, skincolornum_t color, tic_t delay);
|
||||
void K_SpawnLandMineExplosion(mobj_t *source, skincolornum_t color, tic_t delay);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include "k_objects.h"
|
||||
#include "k_powerup.h"
|
||||
#include "k_hud.h" // K_AddMessage
|
||||
#include "p_mobj.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
tic_t K_PowerUpRemaining(const player_t* player, kartitems_t powerup)
|
||||
{
|
||||
|
|
@ -88,6 +90,16 @@ void K_GivePowerUp(player_t* player, kartitems_t powerup, tic_t time)
|
|||
}
|
||||
break;
|
||||
|
||||
case POWERUP_POINTS:
|
||||
K_AddMessageForPlayer(player, "Got 6 POINTS!", true, false);
|
||||
K_GivePointsToPlayer(player, nullptr, 6);
|
||||
|
||||
if (!P_MobjWasRemoved(player->mo))
|
||||
{
|
||||
S_StartSound(player->mo, sfx_token);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
173
src/k_vote.c
173
src/k_vote.c
|
|
@ -76,6 +76,8 @@
|
|||
#define ARM_FRAMES (4)
|
||||
#define BULB_FRAMES (4)
|
||||
|
||||
#define SELECTOR_FRAMES (2)
|
||||
|
||||
#define CATCHER_SPEED (8*FRACUNIT)
|
||||
#define CATCHER_Y_OFFSET (48*FRACUNIT)
|
||||
#define CATCHER_OFFSCREEN (-CATCHER_Y_OFFSET * 2)
|
||||
|
|
@ -91,6 +93,10 @@
|
|||
#define SELECTION_SPACING_H (SELECTION_HEIGHT + SELECTION_SPACE)
|
||||
#define SELECTION_HOP (10*FRACUNIT)
|
||||
|
||||
#define SELECTOR_SPACE (8*FRACUNIT)
|
||||
#define SELECTOR_Y ((SELECTION_HEIGHT / 2) + SELECTOR_SPACE)
|
||||
#define SELECTOR_HEIGHT ((30*FRACUNIT) + SELECTOR_SPACE)
|
||||
|
||||
#define PILE_WIDTH (46*FRACUNIT)
|
||||
#define PILE_HEIGHT ((PILE_WIDTH * BASEVIDHEIGHT) / BASEVIDWIDTH)
|
||||
#define PILE_SPACE (4*FRACUNIT)
|
||||
|
|
@ -146,6 +152,7 @@ typedef struct
|
|||
SINT8 selection;
|
||||
UINT8 delay;
|
||||
boolean sentTimeOutVote;
|
||||
fixed_t x, destX;
|
||||
} y_vote_player;
|
||||
|
||||
// Vote "pile" data. Objects for each vote scattered about.
|
||||
|
|
@ -188,6 +195,13 @@ typedef struct
|
|||
fixed_t hop;
|
||||
} y_vote_draw_level;
|
||||
|
||||
// Voting selector drawing
|
||||
typedef struct
|
||||
{
|
||||
fixed_t x;
|
||||
fixed_t destX;
|
||||
} y_vote_draw_selector;
|
||||
|
||||
// General vote drawing
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -206,6 +220,10 @@ typedef struct
|
|||
|
||||
fixed_t selectTransition;
|
||||
y_vote_draw_level levels[VOTE_NUM_LEVELS];
|
||||
|
||||
patch_t *selector_arrow;
|
||||
patch_t *selector_letter[MAXSPLITSCREENPLAYERS][2];
|
||||
y_vote_draw_selector selectors[MAXSPLITSCREENPLAYERS];
|
||||
} y_vote_draw;
|
||||
|
||||
static y_vote_data vote = {0};
|
||||
|
|
@ -241,6 +259,29 @@ boolean Y_PlayerIDCanVote(const UINT8 playerId)
|
|||
return true;
|
||||
}
|
||||
|
||||
static boolean Y_PlayerCanSelect(const UINT8 localId)
|
||||
{
|
||||
const UINT8 p = g_localplayers[localId];
|
||||
|
||||
if (g_pickedVote != VOTE_NOT_PICKED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_votes[p] != VOTE_NOT_PICKED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vote.players[localId].catcher.action != CATCHER_NA
|
||||
|| vote.players[localId].catcher.delay > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Y_PlayerIDCanVote(p);
|
||||
}
|
||||
|
||||
static void Y_SortPile(void)
|
||||
{
|
||||
UINT8 numVotes = 0;
|
||||
|
|
@ -697,10 +738,61 @@ static void Y_DrawVoteBackground(void)
|
|||
bgTimer += renderdeltatics;
|
||||
}
|
||||
|
||||
static void Y_DrawVoteSelector(const fixed_t y, const fixed_t time, const UINT8 localPlayer)
|
||||
{
|
||||
const fixed_t destX = SELECTION_X + (vote.players[localPlayer].selection * SELECTION_SPACING_W);
|
||||
|
||||
vote_draw.selectors[localPlayer].x += FixedMul(
|
||||
(destX - vote_draw.selectors[localPlayer].x) * 3 / 4,
|
||||
renderdeltatics
|
||||
);
|
||||
|
||||
if (Y_PlayerCanSelect(localPlayer) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const UINT8 freq = 7;
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
if (splitscreen > 0)
|
||||
{
|
||||
const UINT8 blink = ((time / freq / FRACUNIT) & 1);
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, players[ g_localplayers[localPlayer] ].skincolor, GTC_CACHE);
|
||||
|
||||
V_DrawFixedPatch(
|
||||
vote_draw.selectors[localPlayer].x, y - SELECTOR_Y - (9*FRACUNIT),
|
||||
FRACUNIT, 0,
|
||||
vote_draw.selector_letter[localPlayer][blink],
|
||||
colormap
|
||||
);
|
||||
}
|
||||
|
||||
fixed_t bob = FixedMul((time / freq * 2) + (FRACUNIT / 2), ANGLE_90);
|
||||
if (localPlayer & 1)
|
||||
{
|
||||
bob = FCOS(bob);
|
||||
}
|
||||
else
|
||||
{
|
||||
bob = FSIN(bob);
|
||||
}
|
||||
|
||||
V_DrawFixedPatch(
|
||||
vote_draw.selectors[localPlayer].x, y - SELECTOR_Y + bob,
|
||||
FRACUNIT, 0,
|
||||
vote_draw.selector_arrow,
|
||||
colormap
|
||||
);
|
||||
}
|
||||
|
||||
static void Y_DrawVoteSelection(fixed_t offset)
|
||||
{
|
||||
static fixed_t selectorTimer = 0;
|
||||
|
||||
fixed_t x = SELECTION_X;
|
||||
fixed_t y = SELECTION_Y + FixedMul(offset, SELECTION_HEIGHT * 2);
|
||||
fixed_t y = SELECTION_Y + FixedMul(offset, (SELECTION_HEIGHT + SELECTOR_HEIGHT) * 2);
|
||||
INT32 i;
|
||||
|
||||
//
|
||||
|
|
@ -709,7 +801,6 @@ static void Y_DrawVoteSelection(fixed_t offset)
|
|||
for (i = 0; i < VOTE_NUM_LEVELS; i++)
|
||||
{
|
||||
boolean selected = false;
|
||||
INT32 flags = 0;
|
||||
fixed_t destHop = 0;
|
||||
INT32 j;
|
||||
|
||||
|
|
@ -743,7 +834,7 @@ static void Y_DrawVoteSelection(fixed_t offset)
|
|||
|
||||
Y_DrawVoteThumbnail(
|
||||
x, y - vote_draw.levels[i].hop,
|
||||
SELECTION_WIDTH, flags,
|
||||
SELECTION_WIDTH, 0,
|
||||
i, (selected == false),
|
||||
-1
|
||||
);
|
||||
|
|
@ -758,6 +849,31 @@ static void Y_DrawVoteSelection(fixed_t offset)
|
|||
{
|
||||
Y_DrawCatcher(&vote.players[i].catcher);
|
||||
}
|
||||
|
||||
if (offset != FRACUNIT)
|
||||
{
|
||||
//
|
||||
// Draw splitscreen selectors
|
||||
//
|
||||
selectorTimer += renderdeltatics;
|
||||
|
||||
//if (splitscreen > 0)
|
||||
{
|
||||
const UINT8 priority = vote.tic % (splitscreen + 1);
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (i == priority)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Y_DrawVoteSelector(y, selectorTimer, i);
|
||||
}
|
||||
|
||||
Y_DrawVoteSelector(y, selectorTimer, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Y_DrawVotePile(void)
|
||||
|
|
@ -1013,6 +1129,7 @@ static void Y_TickPlayerCatcher(const UINT8 localPlayer)
|
|||
{
|
||||
D_ModifyClientVote(g_localplayers[localPlayer], vote.players[localPlayer].selection);
|
||||
catcher->action = CATCHER_NA;
|
||||
catcher->delay = 5;
|
||||
S_StopSoundByNum(sfx_kc37);
|
||||
}
|
||||
break;
|
||||
|
|
@ -1191,28 +1308,6 @@ static void Y_TickVoteRoulette(void)
|
|||
}
|
||||
}
|
||||
|
||||
static boolean Y_PlayerCanSelect(const UINT8 localId)
|
||||
{
|
||||
const UINT8 p = g_localplayers[localId];
|
||||
|
||||
if (g_pickedVote != VOTE_NOT_PICKED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_votes[p] != VOTE_NOT_PICKED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vote.players[localId].catcher.action != CATCHER_NA)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Y_PlayerIDCanVote(p);
|
||||
}
|
||||
|
||||
static void Y_TryMapAngerVote(void)
|
||||
{
|
||||
SINT8 angryMaps[VOTE_NUM_LEVELS] = { -1 };
|
||||
|
|
@ -1491,7 +1586,7 @@ void Y_VoteTicker(void)
|
|||
//
|
||||
static void Y_InitVoteDrawing(void)
|
||||
{
|
||||
INT32 i = 0;
|
||||
INT32 i = 0, j = 0;
|
||||
|
||||
vote_draw.ruby_icon = W_CachePatchName("RUBYICON", PU_STATIC);
|
||||
|
||||
|
|
@ -1555,6 +1650,20 @@ static void Y_InitVoteDrawing(void)
|
|||
vote_draw.levels[i].str[sizeof vote_draw.levels[i].str - 1] = '\0';
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
y_vote_player *const player = &vote.players[i];
|
||||
|
||||
vote_draw.selectors[i].x = vote_draw.selectors[i].destX = SELECTION_X + (player->selection * SELECTION_SPACING_W);
|
||||
|
||||
for (j = 0; j < SELECTOR_FRAMES; j++)
|
||||
{
|
||||
vote_draw.selector_letter[i][j] = W_CachePatchName(va("VSSPTR%c%d", 'A' + i, j + 1), PU_STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
vote_draw.selector_arrow = W_CachePatchName("VSSPTR1", PU_STATIC);
|
||||
|
||||
vote_draw.selectTransition = FRACUNIT;
|
||||
}
|
||||
|
||||
|
|
@ -1581,6 +1690,8 @@ void Y_StartVote(void)
|
|||
y_vote_player *const player = &vote.players[i];
|
||||
y_vote_catcher *const catcher = &player->catcher;
|
||||
|
||||
player->selection = (i % VOTE_NUM_LEVELS);
|
||||
|
||||
catcher->action = CATCHER_NA;
|
||||
catcher->small = false;
|
||||
catcher->player = -1;
|
||||
|
|
@ -1641,6 +1752,16 @@ static void Y_UnloadVoteData(void)
|
|||
UNLOAD(vote_draw.catcher_bulb[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < MAXSPLITSCREENPLAYERS; j++)
|
||||
{
|
||||
for (i = 0; i < SELECTOR_FRAMES; i++)
|
||||
{
|
||||
UNLOAD(vote_draw.selector_letter[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
UNLOAD(vote_draw.selector_arrow);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1097,7 +1097,7 @@ static int lib_pPlayerZMovement(lua_State *L)
|
|||
static int lib_pAddPlayerScore(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
UINT32 amount = (UINT32)luaL_checkinteger(L, 2);
|
||||
INT32 amount = (UINT32)luaL_checkinteger(L, 2);
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!player)
|
||||
|
|
|
|||
|
|
@ -695,10 +695,12 @@ Obj_MonitorOnDeath
|
|||
K_ItemResultToType(result),
|
||||
K_ItemResultToAmount(result)));
|
||||
|
||||
drop->momz /= 2; // This is player-locked, so no need to throw it high
|
||||
|
||||
if (!P_MobjWasRemoved(source) && source->player)
|
||||
{
|
||||
P_SetTarget(&drop->tracer, source);
|
||||
drop->extravalue1 = 6*TICRATE;
|
||||
drop->extravalue1 = 5*TICRATE;
|
||||
drop->colorized = true;
|
||||
drop->color = source->player->skincolor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,8 +147,10 @@ void Obj_RandomItemVisuals(mobj_t *mobj)
|
|||
|
||||
boolean Obj_RandomItemSpawnIn(mobj_t *mobj)
|
||||
{
|
||||
// We don't want item spawnpoints to be visible during
|
||||
// POSITION in Battle.
|
||||
// battleprisons isn't set in time to do this on spawn. GROAN
|
||||
if ((mobj->flags2 & MF2_BOSSFLEE) && (gametyperules & GTR_BUMPERS) && !battleprisons)
|
||||
if ((mobj->flags2 & MF2_BOSSFLEE) && (gametyperules & (GTR_CIRCUIT|GTR_PAPERITEMS)) == GTR_PAPERITEMS && !battleprisons)
|
||||
mobj->renderflags |= RF_DONTDRAW;
|
||||
|
||||
if ((leveltime == starttime) && !(gametyperules & GTR_CIRCUIT) && (mobj->flags2 & MF2_BOSSFLEE)) // here on map start?
|
||||
|
|
|
|||
|
|
@ -1017,8 +1017,7 @@ void VS_BlendEye_Damage(mobj_t *mobj, mobj_t *inflictor, mobj_t *source, INT32 d
|
|||
|
||||
if (source && source->player)
|
||||
{
|
||||
P_AddPlayerScore(source->player, 1);
|
||||
K_SpawnBattlePoints(source->player, NULL, 1);
|
||||
K_GivePointsToPlayer(source->player, NULL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1761,10 +1761,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
|
||||
K_CheckBumpers();
|
||||
|
||||
if (target->player->roundscore > 1)
|
||||
target->player->roundscore -= 2;
|
||||
else
|
||||
target->player->roundscore = 0;
|
||||
P_AddPlayerScore(target->player, -2);
|
||||
}
|
||||
|
||||
target->player->trickpanel = TRICKSTATE_NONE;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ extern consvar_t cv_tilting;
|
|||
|
||||
extern fixed_t t_cam_dist[MAXSPLITSCREENPLAYERS], t_cam_height[MAXSPLITSCREENPLAYERS], t_cam_rotate[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
void P_AddPlayerScore(player_t *player, UINT32 amount);
|
||||
void P_AddPlayerScore(player_t *player, INT32 amount);
|
||||
void P_ResetCamera(player_t *player, camera_t *thiscam);
|
||||
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
|
||||
void P_SlideCameraMove(camera_t *thiscam);
|
||||
|
|
|
|||
294
src/p_mobj.c
294
src/p_mobj.c
|
|
@ -5862,6 +5862,29 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
P_SpawnGhostMobj(mobj);
|
||||
P_SpawnGhostMobj(mobj->target);
|
||||
}
|
||||
|
||||
// And because this needs to inherit player-lock renderflags,
|
||||
// may as well do that logic in here too. Groooooooooss
|
||||
boolean locked = true;
|
||||
UINT32 lockflag = RF_TRANS40;
|
||||
if (!mobj->target->extravalue1)
|
||||
locked = false;
|
||||
else if (mobj->target->extravalue1 < TICRATE && (mobj->target->extravalue1 % 2))
|
||||
locked = false;
|
||||
|
||||
mobj->target->colorized = false;
|
||||
mobj->target->renderflags &= ~lockflag;
|
||||
mobj->renderflags &= ~lockflag;
|
||||
if (locked)
|
||||
{
|
||||
mobj->target->colorized = true;
|
||||
if ((r_splitscreen == 0) && !P_MobjWasRemoved(mobj->target->tracer)
|
||||
&& mobj->target->tracer->player && !P_IsDisplayPlayer(mobj->target->tracer->player))
|
||||
{
|
||||
mobj->target->renderflags |= lockflag;
|
||||
mobj->renderflags |= lockflag;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -6234,259 +6257,6 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
|||
mobj->renderflags ^= RF_DONTDRAW;
|
||||
}
|
||||
break;
|
||||
|
||||
// see also K_drawKartItem in k_hud.c
|
||||
case MT_PLAYERARROW: // FIXME: Delete this object, attach to name tags instead.
|
||||
if (mobj->target && mobj->target->health
|
||||
&& mobj->target->player && !mobj->target->player->spectator
|
||||
&& mobj->target->health && mobj->target->player->playerstate != PST_DEAD
|
||||
/*&& players[displayplayers[0]].mo && !players[displayplayers[0]].spectator*/)
|
||||
{
|
||||
fixed_t scale = 3*mobj->target->scale;
|
||||
mobj->color = mobj->target->color;
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
|
||||
if (!(gametyperules & GTR_BUMPERS)
|
||||
#if 1 // Set to 0 to test without needing to host
|
||||
|| (P_IsDisplayPlayer(mobj->target->player))
|
||||
#endif
|
||||
)
|
||||
mobj->renderflags |= RF_DONTDRAW;
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = mobj->target->x;
|
||||
mobj->y = mobj->target->y;
|
||||
|
||||
mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's
|
||||
|
||||
if (!r_splitscreen && players[displayplayers[0]].mo)
|
||||
{
|
||||
scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x,
|
||||
players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
|
||||
if (scale > 16*mobj->target->scale)
|
||||
scale = 16*mobj->target->scale;
|
||||
}
|
||||
mobj->destscale = scale;
|
||||
|
||||
if (!(mobj->target->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
mobj->z = mobj->target->z + mobj->target->height + (16*mobj->target->scale);
|
||||
mobj->eflags &= ~MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->z = mobj->target->z - mobj->target->height - (16*mobj->target->scale);
|
||||
mobj->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
P_SetThingPosition(mobj);
|
||||
|
||||
if (!mobj->tracer)
|
||||
{
|
||||
mobj_t *overlay = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY);
|
||||
P_SetTarget(&mobj->tracer, overlay);
|
||||
P_SetTarget(&mobj->tracer->target, mobj);
|
||||
P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM);
|
||||
P_SetScale(mobj->tracer, (mobj->tracer->destscale = mobj->scale));
|
||||
}
|
||||
|
||||
// Do this in an easy way
|
||||
if (mobj->target->player->itemRoulette.active)
|
||||
{
|
||||
mobj->tracer->color = mobj->target->player->skincolor;
|
||||
mobj->tracer->colorized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->tracer->color = SKINCOLOR_NONE;
|
||||
mobj->tracer->colorized = false;
|
||||
}
|
||||
|
||||
if (!(mobj->renderflags & RF_DONTDRAW))
|
||||
{
|
||||
//const INT32 numberdisplaymin = ((mobj->target->player->itemtype == KITEM_ORBINAUT) ? 5 : 2);
|
||||
|
||||
// Set it to use the correct states for its condition
|
||||
if (mobj->target->player->itemRoulette.active)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = 1 | FF_FULLBRIGHT;
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
else if (mobj->target->player->stealingtimer < 0)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO;
|
||||
if (leveltime & 2)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
else if ((mobj->target->player->stealingtimer > 0) && (leveltime & 2))
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO;
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
else if (mobj->target->player->eggmanexplode > 1)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_EGGMAN;
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
else if (mobj->target->player->rocketsneakertimer > 1)
|
||||
{
|
||||
//itembar = mobj->target->player->rocketsneakertimer; -- not today satan
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_ROCKETSNEAKER;
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
else if (mobj->target->player->itemtype && mobj->target->player->itemamount > 0)
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
|
||||
switch (mobj->target->player->itemtype)
|
||||
{
|
||||
case KITEM_ORBINAUT:
|
||||
mobj->tracer->sprite = SPR_ITMO;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|K_GetOrbinautItemFrame(mobj->target->player->itemamount);
|
||||
break;
|
||||
case KITEM_INVINCIBILITY:
|
||||
mobj->tracer->sprite = SPR_ITMI;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|K_GetInvincibilityItemFrame();
|
||||
break;
|
||||
case KITEM_SAD:
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT;
|
||||
break;
|
||||
default:
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|(mobj->target->player->itemtype);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mobj->target->player->itemflags & IF_ITEMOUT)
|
||||
{
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
else
|
||||
mobj->tracer->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
else
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW);
|
||||
P_SetMobjState(mobj->tracer, S_PLAYERARROW_ITEM);
|
||||
}
|
||||
|
||||
mobj->tracer->destscale = scale;
|
||||
|
||||
#if 0
|
||||
if (mobj->target->player->itemamount >= numberdisplaymin
|
||||
&& mobj->target->player->itemamount <= 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V
|
||||
{
|
||||
mobj_t *number = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY);
|
||||
mobj_t *numx = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY);
|
||||
|
||||
P_SetTarget(&number->target, mobj);
|
||||
P_SetMobjState(number, S_PLAYERARROW_NUMBER);
|
||||
P_SetScale(number, mobj->scale);
|
||||
number->destscale = scale;
|
||||
number->frame = FF_FULLBRIGHT|(mobj->target->player->itemamount);
|
||||
|
||||
P_SetTarget(&numx->target, mobj);
|
||||
P_SetMobjState(numx, S_PLAYERARROW_X);
|
||||
P_SetScale(numx, mobj->scale);
|
||||
numx->destscale = scale;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (K_IsPlayerWanted(mobj->target->player) && mobj->movecount != 1)
|
||||
{
|
||||
mobj_t *wanted = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PLAYERWANTED);
|
||||
P_SetTarget(&wanted->target, mobj->target);
|
||||
P_SetTarget(&wanted->tracer, mobj);
|
||||
P_SetScale(wanted, mobj->scale);
|
||||
wanted->destscale = scale;
|
||||
mobj->movecount = 1;
|
||||
}
|
||||
else if (!K_IsPlayerWanted(mobj->target->player))
|
||||
#endif
|
||||
mobj->movecount = 0;
|
||||
}
|
||||
else
|
||||
mobj->tracer->renderflags |= RF_DONTDRAW;
|
||||
}
|
||||
else if (mobj->health > 0)
|
||||
{
|
||||
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case MT_PLAYERWANTED:
|
||||
if (mobj->target && mobj->target->health && mobj->tracer
|
||||
&& mobj->target->player && !mobj->target->player->spectator
|
||||
&& mobj->target->health && mobj->target->player->playerstate != PST_DEAD
|
||||
&& players[g_localplayers[0]].mo && !players[g_localplayers[0]].spectator)
|
||||
{
|
||||
fixed_t scale = 3*mobj->target->scale;
|
||||
|
||||
if (!K_IsPlayerWanted(mobj->target->player))
|
||||
{
|
||||
mobj->tracer->movecount = 0;
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mobj->tracer->renderflags & RF_DONTDRAW)
|
||||
mobj->renderflags |= RF_DONTDRAW;
|
||||
else
|
||||
mobj->renderflags &= ~RF_DONTDRAW;
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = mobj->target->x;
|
||||
mobj->y = mobj->target->y;
|
||||
|
||||
if (!r_splitscreen && players[displayplayers[0]].mo)
|
||||
{
|
||||
scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x,
|
||||
players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
|
||||
if (scale > 16*mobj->target->scale)
|
||||
scale = 16*mobj->target->scale;
|
||||
}
|
||||
mobj->destscale = scale;
|
||||
|
||||
if (!(mobj->target->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
mobj->z = mobj->target->z + mobj->target->height + (16*mobj->target->scale) + (64*scale);
|
||||
mobj->eflags &= ~MFE_VERTICALFLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->z = mobj->target->z - mobj->target->height - (16*mobj->target->scale) - (64*scale);
|
||||
mobj->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
P_SetThingPosition(mobj);
|
||||
}
|
||||
else if (mobj->health > 0)
|
||||
{
|
||||
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case MT_ITEMCAPSULE_PART:
|
||||
P_ItemCapsulePartThinker(mobj);
|
||||
|
||||
|
|
@ -7363,14 +7133,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
K_UpdateMobjItemOverlay(mobj, mobj->threshold, mobj->movecount);
|
||||
|
||||
// ACHTUNG HACK - this is the player-lock timer used when breaking monitors,
|
||||
// but the visual side-effects of this are in the MT_OVERLAY thinker so that
|
||||
// the backdrop can also go transparent. EUUUAUUAUUAAAUUUUGGGHGHHHHHHHGSSS
|
||||
if (mobj->extravalue1 > 0)
|
||||
{
|
||||
mobj->extravalue1--;
|
||||
if (mobj->extravalue1 < TICRATE)
|
||||
{
|
||||
mobj->colorized = mobj->extravalue1 & 1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MT_ITEMCAPSULE:
|
||||
|
|
@ -12316,14 +12084,6 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
K_InitWavedashIndicator(p);
|
||||
K_InitTrickIndicator(p);
|
||||
|
||||
if (gametyperules & GTR_ITEMARROWS)
|
||||
{
|
||||
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW);
|
||||
P_SetTarget(&overheadarrow->target, mobj);
|
||||
overheadarrow->renderflags |= RF_DONTDRAW;
|
||||
P_SetScale(overheadarrow, mobj->destscale);
|
||||
}
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && !p->spectator)
|
||||
{
|
||||
mobj->health = K_BumpersToHealth(K_StartingBumperCount());
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives)
|
|||
}
|
||||
|
||||
// Adds to the player's score
|
||||
void P_AddPlayerScore(player_t *player, UINT32 amount)
|
||||
void P_AddPlayerScore(player_t *player, INT32 amount)
|
||||
{
|
||||
if (!((gametyperules & GTR_POINTLIMIT)))
|
||||
return;
|
||||
|
|
@ -495,8 +495,11 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
|
|||
if (player->exiting) // srb2kart
|
||||
return;
|
||||
|
||||
// Don't underflow.
|
||||
// Don't go above MAXSCORE.
|
||||
if (player->roundscore + amount < MAXSCORE)
|
||||
if (amount < 0 && (UINT32)-amount > player->roundscore)
|
||||
player->roundscore = 0;
|
||||
else if (player->roundscore + amount < MAXSCORE)
|
||||
player->roundscore += amount;
|
||||
else
|
||||
player->roundscore = MAXSCORE;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
/// \brief BSP traversal, handling of LineSegs for rendering
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <tracy/tracy/Tracy.hpp>
|
||||
|
||||
|
|
@ -31,7 +32,7 @@
|
|||
|
||||
#include "k_terrain.h"
|
||||
|
||||
extern "C" consvar_t cv_debugfinishline;
|
||||
extern "C" consvar_t cv_debugfinishline, cv_debugrender_freezebsp;
|
||||
|
||||
seg_t *curline;
|
||||
side_t *sidedef;
|
||||
|
|
@ -53,6 +54,9 @@ INT32 doorclosed;
|
|||
// can block off the BSP across that seg.
|
||||
boolean g_walloffscreen;
|
||||
|
||||
static std::vector<std::vector<INT32>> node_cache;
|
||||
static std::vector<INT32>* current_node_cache;
|
||||
|
||||
boolean R_NoEncore(sector_t *sector, levelflat_t *flat, boolean ceiling)
|
||||
{
|
||||
const boolean invertEncore = (sector->flags & MSF_INVERTENCORE);
|
||||
|
|
@ -1420,5 +1424,46 @@ void R_RenderBSPNode(INT32 bspnum)
|
|||
portalcullsector = NULL;
|
||||
}
|
||||
|
||||
R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
|
||||
bspnum = (bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
|
||||
R_Subsector(bspnum);
|
||||
|
||||
if (current_node_cache)
|
||||
{
|
||||
current_node_cache->push_back(bspnum);
|
||||
}
|
||||
}
|
||||
|
||||
static bool render_cache(size_t cachenum)
|
||||
{
|
||||
if (node_cache.empty() && !cv_debugrender_freezebsp.value)
|
||||
{
|
||||
current_node_cache = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cv_debugrender_freezebsp.value)
|
||||
{
|
||||
// free cache
|
||||
node_cache = {};
|
||||
current_node_cache = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node_cache.size() <= cachenum)
|
||||
{
|
||||
node_cache.resize(cachenum + 1);
|
||||
current_node_cache = &node_cache[cachenum];
|
||||
return false;
|
||||
}
|
||||
|
||||
for (INT32 bspnum : node_cache[cachenum])
|
||||
R_Subsector(bspnum);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void R_RenderFirstBSPNode(size_t cachenum)
|
||||
{
|
||||
if (!render_cache(cachenum))
|
||||
R_RenderBSPNode((INT32)numnodes - 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ void R_ClearClipSegs(void);
|
|||
void R_PortalClearClipSegs(INT32 start, INT32 end);
|
||||
void R_ClearDrawSegs(void);
|
||||
void R_RenderBSPNode(INT32 bspnum);
|
||||
void R_RenderFirstBSPNode(size_t cachenum);
|
||||
|
||||
// determines when a given sector shouldn't abide by the encoremap's palette.
|
||||
// no longer a static since this is used for encore in hw_main.c as well now:
|
||||
|
|
|
|||
|
|
@ -263,7 +263,19 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
|
|||
|
||||
// -1 is the lower clamp bound because column posts have a "safe" byte before the real data
|
||||
// and a few bytes after as well
|
||||
*dest = R_DrawColumnPixel<Type>(dc, dest, std::clamp(frac >> FRACBITS, npow2min, npow2max));
|
||||
//*dest = R_DrawColumnPixel<Type>(dc, dest, std::clamp(frac >> FRACBITS, npow2min, npow2max));
|
||||
{
|
||||
// jartha: faster on my AMD FX-6300 CPU.
|
||||
// Faster than ternaries, faster than std::min/std::max. Don't ask me why.
|
||||
// I tested by viewing a non-PO2 texture from a consistent distance so it covered the entire screen.
|
||||
// The framerate difference was about 50 frames at 640x400.
|
||||
INT32 n = frac >> FRACBITS;
|
||||
if (n < npow2min)
|
||||
n = npow2min;
|
||||
if (n > npow2max)
|
||||
n = npow2max;
|
||||
*dest = R_DrawColumnPixel<Type>(dc, dest, n);
|
||||
}
|
||||
|
||||
dest += vid.width;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ INT64 mytotal = 0;
|
|||
#endif
|
||||
//profile stuff ---------------------------------------------------------
|
||||
|
||||
extern "C" consvar_t cv_debugrender_visplanes;
|
||||
|
||||
// Fineangles in the SCREENWIDTH wide window.
|
||||
#define FIELDOFVIEW 2048
|
||||
|
||||
|
|
@ -1454,13 +1456,13 @@ static void Mask_Post (maskcount_t* m)
|
|||
// ================
|
||||
|
||||
// viewx, viewy, viewangle, all that good stuff must be set
|
||||
static void R_RenderViewpoint(maskcount_t* mask)
|
||||
static void R_RenderViewpoint(maskcount_t* mask, INT32 cachenum)
|
||||
{
|
||||
Mask_Pre(mask);
|
||||
|
||||
curdrawsegs = ds_p;
|
||||
|
||||
R_RenderBSPNode((INT32)numnodes - 1);
|
||||
R_RenderFirstBSPNode(cachenum);
|
||||
R_AddPrecipitationSprites();
|
||||
|
||||
Mask_Post(mask);
|
||||
|
|
@ -1516,7 +1518,7 @@ void R_RenderPlayerView(void)
|
|||
|
||||
srb2::ThreadPool::Sema tp_sema;
|
||||
srb2::g_main_threadpool->begin_sema();
|
||||
R_RenderViewpoint(&masks[nummasks - 1]);
|
||||
R_RenderViewpoint(&masks[nummasks - 1], nummasks - 1);
|
||||
|
||||
ps_bsptime = I_GetPreciseTime() - ps_bsptime;
|
||||
#ifdef TIMING
|
||||
|
|
@ -1574,7 +1576,7 @@ void R_RenderPlayerView(void)
|
|||
// Render the BSP from the new viewpoint, and clip
|
||||
// any sprites with the new clipsegs and window.
|
||||
|
||||
R_RenderViewpoint(&masks[nummasks - 1]);
|
||||
R_RenderViewpoint(&masks[nummasks - 1], nummasks - 1);
|
||||
|
||||
portalskipprecipmobjs = false;
|
||||
|
||||
|
|
@ -1603,6 +1605,58 @@ void R_RenderPlayerView(void)
|
|||
R_DrawMasked(masks, nummasks);
|
||||
ps_sw_maskedtime = I_GetPreciseTime() - ps_sw_maskedtime;
|
||||
|
||||
if (cv_debugrender_visplanes.value)
|
||||
{
|
||||
for (INT32 i = 0; i < MAXVISPLANES; i++)
|
||||
{
|
||||
for (visplane_t* pl = visplanes[i]; pl; pl = pl->next)
|
||||
{
|
||||
if (pl->minx > pl->maxx)
|
||||
continue;
|
||||
auto col = [](int x, int top, int bot)
|
||||
{
|
||||
if (top > bot)
|
||||
std::swap(top, bot);
|
||||
UINT8* p = &screens[0][x + top * vid.width];
|
||||
while (top <= bot)
|
||||
{
|
||||
*p = 35;
|
||||
p += vid.width;
|
||||
top++;
|
||||
}
|
||||
};
|
||||
auto span = [col](int x, int top, int bot)
|
||||
{
|
||||
if (top <= bot)
|
||||
col(x, top, bot);
|
||||
};
|
||||
INT32 top = pl->top[pl->minx];
|
||||
INT32 bottom = pl->bottom[pl->minx];
|
||||
span(pl->minx, top, bottom);
|
||||
span(pl->maxx, pl->top[pl->maxx], pl->bottom[pl->maxx]);
|
||||
for (INT32 x = pl->minx + 1; x < pl->maxx; ++x)
|
||||
{
|
||||
INT32 new_top = pl->top[x];
|
||||
INT32 new_bottom = pl->bottom[x];
|
||||
if (new_top > new_bottom)
|
||||
continue;
|
||||
if (top > bottom)
|
||||
{
|
||||
col(x, new_top, new_top);
|
||||
col(x, new_bottom, new_bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
col(x, top, new_top);
|
||||
col(x, bottom, new_bottom);
|
||||
}
|
||||
top = new_top;
|
||||
bottom = new_bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// debugrender_portal: fill portals with red, draw over everything
|
||||
if (portal_base && cv_debugrender_portal.value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -251,18 +251,23 @@ void Chain::sticker(patch_t* end_graphic, UINT8 color) const
|
|||
|
||||
Chain::Clipper::Clipper(const Chain& chain)
|
||||
{
|
||||
V_SetClipRect(
|
||||
FloatToFixed(chain.clipx1_),
|
||||
FloatToFixed(chain.clipy1_),
|
||||
FloatToFixed(chain.clipx2_ - chain.clipx1_),
|
||||
FloatToFixed(chain.clipy2_ - chain.clipy1_),
|
||||
chain.flags_
|
||||
);
|
||||
V_SaveClipRect(&save_);
|
||||
|
||||
if (chain.clip_)
|
||||
{
|
||||
V_SetClipRect(
|
||||
FloatToFixed(chain.clipx1_),
|
||||
FloatToFixed(chain.clipy1_),
|
||||
FloatToFixed(chain.clipx2_ - chain.clipx1_),
|
||||
FloatToFixed(chain.clipy2_ - chain.clipy1_),
|
||||
chain.flags_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Chain::Clipper::~Clipper()
|
||||
{
|
||||
V_ClearClipRect();
|
||||
V_RestoreClipRect(&save_);
|
||||
}
|
||||
|
||||
patch_t* Draw::cache_patch(const char* name)
|
||||
|
|
|
|||
|
|
@ -154,10 +154,16 @@ public:
|
|||
Chain& clipx() { return clipx(x_, x_ + width_); }
|
||||
Chain& clipy() { return clipy(y_, y_ + height_); }
|
||||
|
||||
// True to use internal clipping state
|
||||
// False to use global state (default)
|
||||
// Changing the clipping dimensions implicitly sets
|
||||
// this to true
|
||||
Chain& clip(bool yes);
|
||||
|
||||
Chain& colormap(const UINT8* colormap);
|
||||
Chain& colormap(skincolornum_t color);
|
||||
Chain& colormap(INT32 skin, skincolornum_t color);
|
||||
Chain& colorize(skincolornum_t color);
|
||||
Chain& colormap(UINT16 color);
|
||||
Chain& colormap(INT32 skin, UINT16 color);
|
||||
Chain& colorize(UINT16 color);
|
||||
|
||||
void text(const char* str) const { string(str, flags_, font_); }
|
||||
void text(const std::string& str) const { text(str.c_str()); }
|
||||
|
|
@ -195,6 +201,9 @@ public:
|
|||
{
|
||||
explicit Clipper(const Chain& chain);
|
||||
~Clipper();
|
||||
|
||||
private:
|
||||
cliprect_t save_;
|
||||
};
|
||||
|
||||
float x_ = 0.f;
|
||||
|
|
@ -207,6 +216,7 @@ public:
|
|||
float clipx2_ = BASEVIDWIDTH;
|
||||
float clipy1_ = 0.f;
|
||||
float clipy2_ = BASEVIDHEIGHT;
|
||||
bool clip_ = false;
|
||||
|
||||
INT32 flags_ = 0;
|
||||
|
||||
|
|
@ -251,6 +261,7 @@ public:
|
|||
METHOD(stretch);
|
||||
METHOD(clipx);
|
||||
METHOD(clipy);
|
||||
METHOD(clip);
|
||||
METHOD(colormap);
|
||||
METHOD(colorize);
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ inline Draw::Chain& Draw::Chain::clipx(float left, float right)
|
|||
{
|
||||
clipx1_ = left;
|
||||
clipx2_ = right;
|
||||
clip_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -94,6 +95,13 @@ inline Draw::Chain& Draw::Chain::clipy(float top, float bottom)
|
|||
{
|
||||
clipy1_ = top;
|
||||
clipy2_ = bottom;
|
||||
clip_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Draw::Chain& Draw::Chain::clip(bool yes)
|
||||
{
|
||||
clip_ = yes;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -103,19 +111,19 @@ inline Draw::Chain& Draw::Chain::colormap(const UINT8* colormap)
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline Draw::Chain& Draw::Chain::colormap(skincolornum_t color)
|
||||
inline Draw::Chain& Draw::Chain::colormap(UINT16 color)
|
||||
{
|
||||
return colormap(R_GetTranslationColormap(TC_DEFAULT, color, GTC_CACHE));
|
||||
return colormap(R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(color), GTC_CACHE));
|
||||
}
|
||||
|
||||
inline Draw::Chain& Draw::Chain::colormap(INT32 skin, skincolornum_t color)
|
||||
inline Draw::Chain& Draw::Chain::colormap(INT32 skin, UINT16 color)
|
||||
{
|
||||
return colormap(R_GetTranslationColormap(skin, color, GTC_CACHE));
|
||||
return colormap(R_GetTranslationColormap(skin, static_cast<skincolornum_t>(color), GTC_CACHE));
|
||||
}
|
||||
|
||||
inline Draw::Chain& Draw::Chain::colorize(skincolornum_t color)
|
||||
inline Draw::Chain& Draw::Chain::colorize(UINT16 color)
|
||||
{
|
||||
return colormap(R_GetTranslationColormap(TC_RAINBOW, color, GTC_CACHE));
|
||||
return colormap(R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(color), GTC_CACHE));
|
||||
}
|
||||
|
||||
}; // namespace srb2
|
||||
|
|
|
|||
|
|
@ -715,6 +715,16 @@ void V_ClearClipRect(void)
|
|||
cliprect.enabled = false;
|
||||
}
|
||||
|
||||
void V_SaveClipRect(cliprect_t *copy)
|
||||
{
|
||||
*copy = cliprect;
|
||||
}
|
||||
|
||||
void V_RestoreClipRect(const cliprect_t *copy)
|
||||
{
|
||||
cliprect = *copy;
|
||||
}
|
||||
|
||||
static UINT8 hudplusalpha[11] = { 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0};
|
||||
static UINT8 hudminusalpha[11] = { 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5};
|
||||
|
||||
|
|
@ -1015,6 +1025,10 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
|||
}
|
||||
#endif
|
||||
|
||||
UINT32 alphalevel;
|
||||
if ((alphalevel = V_GetAlphaLevel(c)) >= 10)
|
||||
return;
|
||||
|
||||
if (!(c & V_NOSCALESTART))
|
||||
{
|
||||
INT32 dupx = vid.dupx, dupy = vid.dupy;
|
||||
|
|
@ -1081,7 +1095,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
|||
|
||||
g_2d.begin_quad()
|
||||
.patch(nullptr)
|
||||
.color(r / 255.f, g / 255.f, b / 255.f, 1.f)
|
||||
.color(r / 255.f, g / 255.f, b / 255.f, (10 - alphalevel) / 10.f)
|
||||
.rect(x, y, w, h)
|
||||
.done();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ struct cliprect_t
|
|||
const cliprect_t *V_GetClipRect(void);
|
||||
void V_SetClipRect(fixed_t x, fixed_t y, fixed_t w, fixed_t h, INT32 flags);
|
||||
void V_ClearClipRect(void);
|
||||
void V_SaveClipRect(cliprect_t *copy);
|
||||
void V_RestoreClipRect(const cliprect_t *copy);
|
||||
|
||||
// defines for old functions
|
||||
#define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT, s|V_NOSCALESTART|V_NOSCALEPATCH, p, NULL)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue