mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	Add Garden Top arrows
Two arrows. One above the player, floating. One below the player, on the ground. Both arrows use the player's facing angle. Arrows are only visible to their own player (other players can't see them). The floating arrow is a papersprite. You can see the arrow turn with you as you turn your camera. The grounded arrow is a splat with additive blending. It tilts to match the slope of the ground you're driving on.
This commit is contained in:
		
							parent
							
								
									ecec400ca4
								
							
						
					
					
						commit
						b1fac18844
					
				
					 6 changed files with 180 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -3776,6 +3776,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
 | 
			
		|||
	"S_GARDENTOP_SINKING3",
 | 
			
		||||
	"S_GARDENTOP_DEAD",
 | 
			
		||||
	"S_GARDENTOPSPARK",
 | 
			
		||||
	"S_GARDENTOPARROW",
 | 
			
		||||
 | 
			
		||||
	// Caked-Up Booty-Sheet Ghost
 | 
			
		||||
	"S_HYUDORO",
 | 
			
		||||
| 
						 | 
				
			
			@ -5389,6 +5390,7 @@ const char *const MOBJTYPE_LIST[] = {  // array length left dynamic for sanity t
 | 
			
		|||
	"MT_BUBBLESHIELDTRAP",
 | 
			
		||||
	"MT_GARDENTOP",
 | 
			
		||||
	"MT_GARDENTOPSPARK",
 | 
			
		||||
	"MT_GARDENTOPARROW",
 | 
			
		||||
 | 
			
		||||
	"MT_HYUDORO",
 | 
			
		||||
	"MT_HYUDORO_CENTER",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								src/info.c
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								src/info.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -586,6 +586,7 @@ char sprnames[NUMSPRITES + 1][5] =
 | 
			
		|||
	"FLML", // Flame Shield speed lines
 | 
			
		||||
	"FLMF", // Flame Shield flash
 | 
			
		||||
	"GTOP", // Marble Garden Zone Spinning Top
 | 
			
		||||
	"GTAR", // Garden Top Arrow
 | 
			
		||||
	"HYUU", // Hyudoro
 | 
			
		||||
	"GRWP", // Grow
 | 
			
		||||
	"POHB", // Shrink Poh-Bee
 | 
			
		||||
| 
						 | 
				
			
			@ -4370,6 +4371,7 @@ state_t states[NUMSTATES] =
 | 
			
		|||
	{SPR_GTOP, 4, 1, {NULL}, 5, 1, S_GARDENTOP_SINKING1}, // S_GARDENTOP_SINKING3
 | 
			
		||||
	{SPR_GTOP, FF_ANIMATE, 100, {A_Scream}, 5, 1, S_NULL}, // S_GARDENTOP_DEAD
 | 
			
		||||
	{SPR_BDRF, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 5, 2, S_NULL}, // S_GARDENTOPSPARK
 | 
			
		||||
	{SPR_GTAR, FF_FULLBRIGHT, -1, {NULL}, 5, 2, S_NULL}, // S_GARDENTOPARROW
 | 
			
		||||
 | 
			
		||||
	{SPR_HYUU, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_HYUDORO
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -24036,6 +24038,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 | 
			
		|||
		S_NULL          // raisestate
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{           // MT_GARDENTOPARROW
 | 
			
		||||
		-1,             // doomednum
 | 
			
		||||
		S_GARDENTOPARROW, // 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
 | 
			
		||||
		8*FRACUNIT,     // radius
 | 
			
		||||
		54*FRACUNIT,    // height
 | 
			
		||||
		1,              // display offset
 | 
			
		||||
		100,            // mass
 | 
			
		||||
		0,              // damage
 | 
			
		||||
		sfx_None,       // activesound
 | 
			
		||||
		MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP|MF_NOSQUISH, // flags
 | 
			
		||||
		S_NULL          // raisestate
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{           // MT_HYUDORO
 | 
			
		||||
		-1,             // doomednum
 | 
			
		||||
		S_HYUDORO,      // spawnstate
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1137,6 +1137,7 @@ typedef enum sprite
 | 
			
		|||
	SPR_FLML, // Flame Shield speed lines
 | 
			
		||||
	SPR_FLMF, // Flame Shield flash
 | 
			
		||||
	SPR_GTOP, // Marble Garden Zone Spinning Top
 | 
			
		||||
	SPR_GTAR, // Garden Top Arrow
 | 
			
		||||
	SPR_HYUU, // Hyudoro
 | 
			
		||||
	SPR_GRWP, // Grow
 | 
			
		||||
	SPR_POHB, // Shrink Poh-Bee
 | 
			
		||||
| 
						 | 
				
			
			@ -4808,6 +4809,7 @@ typedef enum state
 | 
			
		|||
	S_GARDENTOP_SINKING3,
 | 
			
		||||
	S_GARDENTOP_DEAD,
 | 
			
		||||
	S_GARDENTOPSPARK,
 | 
			
		||||
	S_GARDENTOPARROW,
 | 
			
		||||
 | 
			
		||||
	// Caked-Up Booty-Sheet Ghost
 | 
			
		||||
	S_HYUDORO,
 | 
			
		||||
| 
						 | 
				
			
			@ -6457,6 +6459,7 @@ typedef enum mobj_type
 | 
			
		|||
	MT_BUBBLESHIELDTRAP,
 | 
			
		||||
	MT_GARDENTOP,
 | 
			
		||||
	MT_GARDENTOPSPARK,
 | 
			
		||||
	MT_GARDENTOPARROW,
 | 
			
		||||
 | 
			
		||||
	MT_HYUDORO,
 | 
			
		||||
	MT_HYUDORO_CENTER,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ mobj_t *Obj_GardenTopThrow(player_t *player);
 | 
			
		|||
mobj_t *Obj_GardenTopDestroy(player_t *player);
 | 
			
		||||
void Obj_GardenTopThink(mobj_t *top);
 | 
			
		||||
void Obj_GardenTopSparkThink(mobj_t *spark);
 | 
			
		||||
void Obj_GardenTopArrowThink(mobj_t *arrow);
 | 
			
		||||
boolean Obj_GardenTopPlayerIsGrinding(player_t *player);
 | 
			
		||||
 | 
			
		||||
/* Shrink */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,14 @@ enum {
 | 
			
		|||
#define spark_top(o) ((o)->target)
 | 
			
		||||
#define spark_angle(o) ((o)->movedir)
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	ARROW_OVERHEAD,
 | 
			
		||||
	ARROW_IN_FRONT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define arrow_top(o) ((o)->target)
 | 
			
		||||
#define arrow_kind(o) ((o)->reactiontime)
 | 
			
		||||
 | 
			
		||||
static inline player_t *
 | 
			
		||||
get_rider_player (mobj_t *rider)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -204,6 +212,49 @@ spawn_grind_spark (mobj_t *top)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static mobj_t *
 | 
			
		||||
spawn_arrow
 | 
			
		||||
(		mobj_t * top,
 | 
			
		||||
		UINT32 ff,
 | 
			
		||||
		UINT8 kind)
 | 
			
		||||
{
 | 
			
		||||
	mobj_t *arrow = P_SpawnMobjFromMobj(
 | 
			
		||||
			top, 0, 0, 0, MT_GARDENTOPARROW);
 | 
			
		||||
 | 
			
		||||
	P_SetTarget(&arrow_top(arrow), top);
 | 
			
		||||
	arrow_kind(arrow) = kind;
 | 
			
		||||
 | 
			
		||||
	arrow->frame |= ff;
 | 
			
		||||
 | 
			
		||||
	return arrow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
spawn_arrow_pair (mobj_t *top)
 | 
			
		||||
{
 | 
			
		||||
	{
 | 
			
		||||
		mobj_t *x = spawn_arrow(top,
 | 
			
		||||
				FF_PAPERSPRITE, ARROW_OVERHEAD);
 | 
			
		||||
 | 
			
		||||
		// overhead arrow is slightly smaller
 | 
			
		||||
		P_SetScale(x, (x->destscale = 3 * x->scale / 4));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		mobj_t *x = spawn_arrow(top,
 | 
			
		||||
				FF_FLOORSPRITE | FF_ADD, ARROW_IN_FRONT);
 | 
			
		||||
 | 
			
		||||
		x->renderflags |= RF_SLOPESPLAT | RF_NOSPLATBILLBOARD;
 | 
			
		||||
 | 
			
		||||
		// Let splat be flat, useful later for
 | 
			
		||||
		// Obj_GardenTopArrowThink reverse gravity.
 | 
			
		||||
		x->height = 0;
 | 
			
		||||
 | 
			
		||||
		// Make the arrow wider (sprite length is horizontal).
 | 
			
		||||
		x->spriteyscale = 2*FRACUNIT;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
loop_sfx
 | 
			
		||||
(		mobj_t * top,
 | 
			
		||||
| 
						 | 
				
			
			@ -361,6 +412,25 @@ tilt (mobj_t *top)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
anchor
 | 
			
		||||
(		mobj_t * us,
 | 
			
		||||
		mobj_t * them,
 | 
			
		||||
		angle_t angle,
 | 
			
		||||
		fixed_t radius)
 | 
			
		||||
{
 | 
			
		||||
	const fixed_t x = P_ReturnThrustX(us, angle, radius);
 | 
			
		||||
	const fixed_t y = P_ReturnThrustY(us, angle, radius);
 | 
			
		||||
 | 
			
		||||
	/* FIXME: THIS FUNCTION FUCKING SUCKS */
 | 
			
		||||
	K_FlipFromObject(us, them);
 | 
			
		||||
 | 
			
		||||
	P_MoveOrigin(us, them->x + x, them->y + y,
 | 
			
		||||
			them->z + K_FlipZOffset(us, them));
 | 
			
		||||
 | 
			
		||||
	us->angle = angle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
anchor_top (mobj_t *top)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -375,8 +445,7 @@ anchor_top (mobj_t *top)
 | 
			
		|||
 | 
			
		||||
	tilt(top);
 | 
			
		||||
 | 
			
		||||
	P_MoveOrigin(top, rider->x, rider->y,
 | 
			
		||||
			rider->z + K_FlipZOffset(top, rider));
 | 
			
		||||
	anchor(top, rider, rider->angle, 0);
 | 
			
		||||
 | 
			
		||||
	K_GenericExtraFlagsNoZAdjust(top, rider);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -447,17 +516,8 @@ anchor_spark (mobj_t *spark)
 | 
			
		|||
	mobj_t *rider = top_rider(top);
 | 
			
		||||
	player_t *player = get_rider_player(rider);
 | 
			
		||||
 | 
			
		||||
	const angle_t angle = top->angle + spark_angle(spark);
 | 
			
		||||
	const fixed_t x = P_ReturnThrustX(top, angle, spark->scale);
 | 
			
		||||
	const fixed_t y = P_ReturnThrustY(top, angle, spark->scale);
 | 
			
		||||
 | 
			
		||||
	/* FIXME: THIS FUNCTION FUCKING SUCKS */
 | 
			
		||||
	K_FlipFromObject(spark, top);
 | 
			
		||||
 | 
			
		||||
	P_MoveOrigin(spark, top->x + x, top->y + y,
 | 
			
		||||
			top->z + K_FlipZOffset(spark, top));
 | 
			
		||||
 | 
			
		||||
	spark->angle = angle;
 | 
			
		||||
	anchor(spark, top,
 | 
			
		||||
			(top->angle + spark_angle(spark)), spark->scale);
 | 
			
		||||
 | 
			
		||||
	if (player)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -472,6 +532,39 @@ anchor_spark (mobj_t *spark)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
anchor_arrow_overhead (mobj_t *arrow)
 | 
			
		||||
{
 | 
			
		||||
	mobj_t *top = arrow_top(arrow);
 | 
			
		||||
	mobj_t *rider = top_rider(top);
 | 
			
		||||
 | 
			
		||||
	const fixed_t height =
 | 
			
		||||
		top->height + rider->height + (3 * arrow->height / 4);
 | 
			
		||||
 | 
			
		||||
	arrow->sprzoff = top->sprzoff +
 | 
			
		||||
		(height * P_MobjFlip(arrow));
 | 
			
		||||
 | 
			
		||||
	anchor(arrow, top, rider->angle + ANGLE_180, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
anchor_arrow_in_front (mobj_t *arrow)
 | 
			
		||||
{
 | 
			
		||||
	mobj_t *top = arrow_top(arrow);
 | 
			
		||||
	mobj_t *rider = top_rider(top);
 | 
			
		||||
 | 
			
		||||
	anchor(arrow, top, rider->angle, 2 * rider->radius);
 | 
			
		||||
 | 
			
		||||
	arrow->angle += ANGLE_90;
 | 
			
		||||
 | 
			
		||||
	if (P_IsObjectFlipped(arrow))
 | 
			
		||||
	{
 | 
			
		||||
		arrow->angle += ANGLE_180;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	arrow->floorspriteslope = rider->standingslope;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Obj_GardenTopDeploy (mobj_t *rider)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -497,6 +590,8 @@ Obj_GardenTopDeploy (mobj_t *rider)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	spawn_spark_circle(top, 6);
 | 
			
		||||
 | 
			
		||||
	spawn_arrow_pair(top);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mobj_t *
 | 
			
		||||
| 
						 | 
				
			
			@ -605,6 +700,38 @@ Obj_GardenTopSparkThink (mobj_t *spark)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Obj_GardenTopArrowThink (mobj_t *arrow)
 | 
			
		||||
{
 | 
			
		||||
	mobj_t *top = arrow_top(arrow);
 | 
			
		||||
	mobj_t *rider = top ? top_rider(top) : NULL;
 | 
			
		||||
 | 
			
		||||
	if (!rider)
 | 
			
		||||
	{
 | 
			
		||||
		P_RemoveMobj(arrow);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (arrow_kind(arrow))
 | 
			
		||||
	{
 | 
			
		||||
		case ARROW_OVERHEAD:
 | 
			
		||||
			anchor_arrow_overhead(arrow);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case ARROW_IN_FRONT:
 | 
			
		||||
			anchor_arrow_in_front(arrow);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (rider->player)
 | 
			
		||||
	{
 | 
			
		||||
		// Don't show for other players
 | 
			
		||||
		arrow->renderflags =
 | 
			
		||||
			(arrow->renderflags & ~(RF_DONTDRAW)) |
 | 
			
		||||
			(RF_DONTDRAW & ~(K_GetPlayerDontDrawFlag(rider->player)));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
boolean
 | 
			
		||||
Obj_GardenTopPlayerIsGrinding (player_t *player)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8394,6 +8394,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
 | 
			
		|||
		Obj_GardenTopSparkThink(mobj);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	case MT_GARDENTOPARROW:
 | 
			
		||||
	{
 | 
			
		||||
		Obj_GardenTopArrowThink(mobj);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	case MT_HYUDORO:
 | 
			
		||||
	{
 | 
			
		||||
		Obj_HyudoroThink(mobj);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue