mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	Merge branch 'battle-bimbos-monday' into 'master'
Battle Bimbos Monday thru Friday (The Bimbo Week) Closes #977, #944, and #962 See merge request KartKrew/Kart!1869
This commit is contained in:
		
						commit
						b323c6bdb7
					
				
					 27 changed files with 510 additions and 610 deletions
				
			
		| 
						 | 
				
			
			@ -208,6 +208,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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4102,19 +4102,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",
 | 
			
		||||
| 
						 | 
				
			
			@ -5974,9 +5961,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",
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -7500,6 +7484,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
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -719,14 +719,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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4969,20 +4967,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
 | 
			
		||||
| 
						 | 
				
			
			@ -27272,60 +27256,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
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1283,14 +1283,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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5425,19 +5423,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,
 | 
			
		||||
| 
						 | 
				
			
			@ -7339,9 +7324,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;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1808,10 +1808,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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										293
									
								
								src/p_mobj.c
									
										
									
									
									
								
							
							
						
						
									
										293
									
								
								src/p_mobj.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -5989,6 +5989,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:
 | 
			
		||||
| 
						 | 
				
			
			@ -6406,258 +6429,6 @@ static void P_MobjSceneryThink(mobj_t *mobj)
 | 
			
		|||
		}
 | 
			
		||||
		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_PETSMOKER:
 | 
			
		||||
		if (!(leveltime % 10))
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -7603,14 +7374,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:
 | 
			
		||||
| 
						 | 
				
			
			@ -12951,14 +12720,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());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -570,7 +570,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -578,8 +578,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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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