mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	Merge branch 'more-bot-crudules' into 'master'
More bot crudules See merge request KartKrew/Kart!788
This commit is contained in:
		
						commit
						bc2d4a2d83
					
				
					 9 changed files with 255 additions and 30 deletions
				
			
		
							
								
								
									
										27
									
								
								src/k_bot.c
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								src/k_bot.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -710,7 +710,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
 | 
			
		|||
			if (P_TraceBotTraversal(player->mo, wp->mobj) == false)
 | 
			
		||||
			{
 | 
			
		||||
				// If we can't get a direct path to this waypoint, predict less.
 | 
			
		||||
				distanceleft -= disttonext;
 | 
			
		||||
				distanceleft /= 2;
 | 
			
		||||
				radreduce = FRACUNIT >> 1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -745,6 +745,25 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
 | 
			
		|||
		predict->y += P_ReturnThrustY(NULL, angletonext, min(disttonext, distanceleft) * FRACUNIT);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (player->mo->standingslope != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		const pslope_t *slope = player->mo->standingslope;
 | 
			
		||||
 | 
			
		||||
		if (!(slope->flags & SL_NOPHYSICS) && abs(slope->zdelta) >= FRACUNIT/21)
 | 
			
		||||
		{
 | 
			
		||||
			// Displace the prediction to go against the slope physics.
 | 
			
		||||
			angle_t angle = slope->xydirection;
 | 
			
		||||
 | 
			
		||||
			if (P_MobjFlip(player->mo) * slope->zdelta < 0)
 | 
			
		||||
			{
 | 
			
		||||
				angle ^= ANGLE_180;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			predict->x -= P_ReturnThrustX(NULL, angle, startDist * abs(slope->zdelta));
 | 
			
		||||
			predict->y -= P_ReturnThrustY(NULL, angle, startDist * abs(slope->zdelta));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ps_bots[player - players].prediction += I_GetPreciseTime() - time;
 | 
			
		||||
	return predict;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -875,7 +894,7 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
 | 
			
		|||
	debugMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
 | 
			
		||||
 | 
			
		||||
	debugMobj->color = SKINCOLOR_ORANGE;
 | 
			
		||||
	debugMobj->scale *= 2;
 | 
			
		||||
	P_SetScale(debugMobj, debugMobj->destscale * 2);
 | 
			
		||||
 | 
			
		||||
	debugMobj->tics = 2;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -902,7 +921,7 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
 | 
			
		|||
		radiusMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
 | 
			
		||||
 | 
			
		||||
		radiusMobj->color = SKINCOLOR_YELLOW;
 | 
			
		||||
		radiusMobj->scale /= 2;
 | 
			
		||||
		P_SetScale(debugMobj, debugMobj->destscale / 2);
 | 
			
		||||
 | 
			
		||||
		radiusMobj->tics = 2;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1452,7 +1471,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (spindash == 0)
 | 
			
		||||
	if (spindash == 0 && player->exiting == 0)
 | 
			
		||||
	{
 | 
			
		||||
		// Don't pointlessly try to use rings/sneakers while charging a spindash.
 | 
			
		||||
		// TODO: Allowing projectile items like orbinaut while e-braking would be nice, maybe just pass in the spindash variable?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										220
									
								
								src/k_botitem.c
									
										
									
									
									
								
							
							
						
						
									
										220
									
								
								src/k_botitem.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -486,6 +486,12 @@ static void K_BotItemGenericOrbitShield(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
--------------------------------------------------*/
 | 
			
		||||
static void K_BotItemSneaker(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
{
 | 
			
		||||
	if (P_IsObjectOnGround(player->mo) == false)
 | 
			
		||||
	{
 | 
			
		||||
		// Don't use while mid-air.
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((player->offroad && K_ApplyOffroad(player)) // Stuck in offroad, use it NOW
 | 
			
		||||
		|| K_GetWaypointIsShortcut(player->nextwaypoint) == true // Going toward a shortcut!
 | 
			
		||||
		|| player->speed < K_GetKartSpeed(player, false, true) / 2 // Being slowed down too much
 | 
			
		||||
| 
						 | 
				
			
			@ -518,6 +524,12 @@ static void K_BotItemSneaker(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
--------------------------------------------------*/
 | 
			
		||||
static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
{
 | 
			
		||||
	if (P_IsObjectOnGround(player->mo) == false)
 | 
			
		||||
	{
 | 
			
		||||
		// Don't use while mid-air.
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (player->botvars.itemconfirm > TICRATE)
 | 
			
		||||
	{
 | 
			
		||||
		if (player->sneakertimer == 0 && K_ItemButtonWasDown(player) == false)
 | 
			
		||||
| 
						 | 
				
			
			@ -892,9 +904,9 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------
 | 
			
		||||
	static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
	static void K_BotItemBallhog(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
 | 
			
		||||
		Item usage for Drop Target throwing.
 | 
			
		||||
		Item usage for Ballhog throwing.
 | 
			
		||||
 | 
			
		||||
	Input Arguments:-
 | 
			
		||||
		player - Bot to do this for.
 | 
			
		||||
| 
						 | 
				
			
			@ -903,14 +915,15 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
	Return:-
 | 
			
		||||
		None
 | 
			
		||||
--------------------------------------------------*/
 | 
			
		||||
static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
static void K_BotItemBallhog(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
{
 | 
			
		||||
	const fixed_t topspeed = K_GetKartSpeed(player, false, true);
 | 
			
		||||
	fixed_t radius = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
 | 
			
		||||
	fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
 | 
			
		||||
	SINT8 throwdir = -1;
 | 
			
		||||
	boolean tryLookback = false;
 | 
			
		||||
	UINT8 snipeMul = 2;
 | 
			
		||||
	player_t *target = NULL;
 | 
			
		||||
	boolean hold = false;
 | 
			
		||||
 | 
			
		||||
	if (player->speed > topspeed)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -918,8 +931,6 @@ static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
		snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!!
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	player->botvars.itemconfirm++;
 | 
			
		||||
 | 
			
		||||
	target = K_PlayerInCone(player, radius, 15, false);
 | 
			
		||||
	if (target != NULL)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -943,7 +954,89 @@ static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
		cmd->buttons |= BT_LOOKBACK;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (player->botvars.itemconfirm > 25*TICRATE)
 | 
			
		||||
	if (target != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		// Charge up!
 | 
			
		||||
		hold = true;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// If we lose sight of the target, then we'll just
 | 
			
		||||
		// let go and it'll do a partial-blast.
 | 
			
		||||
 | 
			
		||||
		// If we've been waiting for too long though, then
 | 
			
		||||
		// we'll go for the full charge :)
 | 
			
		||||
		player->botvars.itemconfirm++;
 | 
			
		||||
		hold = (player->botvars.itemconfirm > 10*TICRATE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (hold == true)
 | 
			
		||||
	{
 | 
			
		||||
		cmd->throwdir = KART_FULLTURN * throwdir;
 | 
			
		||||
		cmd->buttons |= BT_ATTACK;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------
 | 
			
		||||
	static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		||||
 | 
			
		||||
		Item usage for Drop Target throwing.
 | 
			
		||||
 | 
			
		||||
	Input Arguments:-
 | 
			
		||||
		player - Bot to do this for.
 | 
			
		||||
		cmd - Bot's ticcmd to edit.
 | 
			
		||||
		turnamt - How hard they currently are turning.
 | 
			
		||||
 | 
			
		||||
	Return:-
 | 
			
		||||
		None
 | 
			
		||||
--------------------------------------------------*/
 | 
			
		||||
static void K_BotItemDropTarget(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		||||
{
 | 
			
		||||
	const fixed_t topspeed = K_GetKartSpeed(player, false, true);
 | 
			
		||||
	fixed_t radius = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
 | 
			
		||||
	SINT8 throwdir = -1;
 | 
			
		||||
	boolean tryLookback = false;
 | 
			
		||||
	UINT8 snipeMul = 2;
 | 
			
		||||
	player_t *target = NULL;
 | 
			
		||||
 | 
			
		||||
	if (player->speed > topspeed)
 | 
			
		||||
	{
 | 
			
		||||
		radius = FixedMul(radius, FixedDiv(player->speed, topspeed));
 | 
			
		||||
		snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!!
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	player->botvars.itemconfirm++;
 | 
			
		||||
 | 
			
		||||
	if (abs(turnamt) >= KART_FULLTURN/2)
 | 
			
		||||
	{
 | 
			
		||||
		player->botvars.itemconfirm += player->botvars.difficulty / 2;
 | 
			
		||||
		throwdir = -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	target = K_PlayerInCone(player, radius, 15, false);
 | 
			
		||||
	if (target != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul);
 | 
			
		||||
		throwdir = 1;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		target = K_PlayerInCone(player, radius, 15, true);
 | 
			
		||||
 | 
			
		||||
		if (target != NULL)
 | 
			
		||||
		{
 | 
			
		||||
			K_ItemConfirmForTarget(player, target, player->botvars.difficulty);
 | 
			
		||||
			throwdir = -1;
 | 
			
		||||
			tryLookback = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (tryLookback == true && throwdir == -1)
 | 
			
		||||
	{
 | 
			
		||||
		cmd->buttons |= BT_LOOKBACK;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE)
 | 
			
		||||
	{
 | 
			
		||||
		K_BotGenericPressItem(player, cmd, throwdir);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1166,6 +1259,92 @@ static void K_BotItemFlame(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------
 | 
			
		||||
	static void K_BotItemGardenTopDeploy(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
 | 
			
		||||
		Item usage for deploying the Garden Top.
 | 
			
		||||
 | 
			
		||||
	Input Arguments:-
 | 
			
		||||
		player - Bot to do this for.
 | 
			
		||||
		cmd - Bot's ticcmd to edit.
 | 
			
		||||
 | 
			
		||||
	Return:-
 | 
			
		||||
		None
 | 
			
		||||
--------------------------------------------------*/
 | 
			
		||||
static void K_BotItemGardenTopDeploy(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
{
 | 
			
		||||
	//if (player->curshield != KSHIELD_TOP)
 | 
			
		||||
	if (player->botvars.itemconfirm++ > 2*TICRATE)
 | 
			
		||||
	{
 | 
			
		||||
		K_BotGenericPressItem(player, cmd, 0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------
 | 
			
		||||
	static void K_BotItemGardenTop(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		||||
 | 
			
		||||
		Item usage for Garden Top movement.
 | 
			
		||||
 | 
			
		||||
	Input Arguments:-
 | 
			
		||||
		player - Bot to do this for.
 | 
			
		||||
		cmd - Bot's ticcmd to edit.
 | 
			
		||||
		turnamt - How hard they currently are turning.
 | 
			
		||||
 | 
			
		||||
	Return:-
 | 
			
		||||
		None
 | 
			
		||||
--------------------------------------------------*/
 | 
			
		||||
static void K_BotItemGardenTop(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		||||
{
 | 
			
		||||
	const fixed_t topspeed = K_GetKartSpeed(player, false, true);
 | 
			
		||||
	fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
 | 
			
		||||
	SINT8 throwdir = -1;
 | 
			
		||||
	UINT8 snipeMul = 1;
 | 
			
		||||
	player_t *target = NULL;
 | 
			
		||||
 | 
			
		||||
	if (player->speed > topspeed)
 | 
			
		||||
	{
 | 
			
		||||
		radius = FixedMul(radius, FixedDiv(player->speed, topspeed));
 | 
			
		||||
		snipeMul = 2; // Confirm faster when you'll throw it with a bunch of extra speed!!
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	player->botvars.itemconfirm++;
 | 
			
		||||
 | 
			
		||||
	target = K_PlayerInCone(player, radius, 15, false);
 | 
			
		||||
	if (target != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul);
 | 
			
		||||
		throwdir = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (player->topdriftheld > 0)
 | 
			
		||||
	{
 | 
			
		||||
		// Grinding in place.
 | 
			
		||||
		// Wait until we're mostly done turning.
 | 
			
		||||
		// Cancel early if we hit max thrust speed.
 | 
			
		||||
		if ((abs(turnamt) >= KART_FULLTURN/8)
 | 
			
		||||
			&& (player->topdriftheld <= GARDENTOP_MAXGRINDTIME))
 | 
			
		||||
		{
 | 
			
		||||
			cmd->buttons |= BT_DRIFT;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		const angle_t maxDelta = ANGLE_11hh;
 | 
			
		||||
		angle_t delta = AngleDelta(player->mo->angle, K_MomentumAngle(player->mo));
 | 
			
		||||
 | 
			
		||||
		if (delta > maxDelta)
 | 
			
		||||
		{
 | 
			
		||||
			// Do we need to turn? Start grinding!
 | 
			
		||||
			cmd->buttons |= BT_DRIFT;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (player->botvars.itemconfirm > 25*TICRATE)
 | 
			
		||||
	{
 | 
			
		||||
		K_BotGenericPressItem(player, cmd, throwdir);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------
 | 
			
		||||
	static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1182,6 +1361,12 @@ static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
 | 
			
		|||
{
 | 
			
		||||
	INT32 saferingsval = 16 - K_GetKartRingPower(player, false);
 | 
			
		||||
 | 
			
		||||
	if (P_IsObjectOnGround(player->mo) == false)
 | 
			
		||||
	{
 | 
			
		||||
		// Don't use while mid-air.
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (player->speed < K_GetKartSpeed(player, false, true) / 2 // Being slowed down too much
 | 
			
		||||
		|| player->speedboost > (FRACUNIT/5)) // Have another type of boost (tethering)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -1242,7 +1427,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		|||
	{
 | 
			
		||||
		// Use rings!
 | 
			
		||||
 | 
			
		||||
		if (leveltime > starttime && !player->exiting)
 | 
			
		||||
		if (leveltime > starttime)
 | 
			
		||||
		{
 | 
			
		||||
			K_BotItemRings(player, cmd);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1293,7 +1478,6 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		|||
					case KITEM_SPB:
 | 
			
		||||
					case KITEM_GROW:
 | 
			
		||||
					case KITEM_SHRINK:
 | 
			
		||||
					case KITEM_HYUDORO:
 | 
			
		||||
					case KITEM_SUPERRING:
 | 
			
		||||
						K_BotItemGenericTap(player, cmd);
 | 
			
		||||
						break;
 | 
			
		||||
| 
						 | 
				
			
			@ -1325,8 +1509,6 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		|||
							K_BotItemGenericOrbitShield(player, cmd);
 | 
			
		||||
						}
 | 
			
		||||
						else if (player->position != 1) // Hold onto orbiting items when in 1st :)
 | 
			
		||||
						/* FALLTHRU */
 | 
			
		||||
					case KITEM_BALLHOG:
 | 
			
		||||
						{
 | 
			
		||||
							K_BotItemOrbinaut(player, cmd);
 | 
			
		||||
						}
 | 
			
		||||
| 
						 | 
				
			
			@ -1352,8 +1534,12 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		|||
						}
 | 
			
		||||
						break;
 | 
			
		||||
					case KITEM_LANDMINE:
 | 
			
		||||
					case KITEM_HYUDORO: // Function re-use, as they have about the same usage.
 | 
			
		||||
						K_BotItemLandmine(player, cmd, turnamt);
 | 
			
		||||
						break;
 | 
			
		||||
					case KITEM_BALLHOG:
 | 
			
		||||
						K_BotItemBallhog(player, cmd);
 | 
			
		||||
						break;
 | 
			
		||||
					case KITEM_DROPTARGET:
 | 
			
		||||
						if (!(player->pflags & PF_ITEMOUT))
 | 
			
		||||
						{
 | 
			
		||||
| 
						 | 
				
			
			@ -1361,7 +1547,17 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
 | 
			
		|||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
							K_BotItemDropTarget(player, cmd);
 | 
			
		||||
							K_BotItemDropTarget(player, cmd, turnamt);
 | 
			
		||||
						}
 | 
			
		||||
						break;
 | 
			
		||||
					case KITEM_GARDENTOP:
 | 
			
		||||
						if (player->curshield != KSHIELD_TOP)
 | 
			
		||||
						{
 | 
			
		||||
							K_BotItemGardenTopDeploy(player, cmd);
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
							K_BotItemGardenTop(player, cmd, turnamt);
 | 
			
		||||
						}
 | 
			
		||||
						break;
 | 
			
		||||
					case KITEM_LIGHTNINGSHIELD:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec)
 | 
			
		|||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sec->offroad > FRACUNIT) // Only care about strong offroad.
 | 
			
		||||
	if (sec->offroad > 0)
 | 
			
		||||
	{
 | 
			
		||||
		return !K_BotCanTakeCut(player);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9067,6 +9067,11 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
 | 
			
		|||
 | 
			
		||||
						if (angledelta < nextbestdelta && momdelta < nextbestmomdelta)
 | 
			
		||||
						{
 | 
			
		||||
							if (waypoint->prevwaypoints[i] == finishline) // NEVER allow finish line.
 | 
			
		||||
							{
 | 
			
		||||
								continue;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							if (P_TraceWaypointTraversal(player->mo, waypoint->prevwaypoints[i]->mobj) == false)
 | 
			
		||||
							{
 | 
			
		||||
								// Save sight checks when all of the other checks pass, so we only do it if we have to
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -361,7 +361,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
 | 
			
		|||
			// remember: huge radius
 | 
			
		||||
			if (closestdist <= rad && checkdist <= rad && finishline != NULL)
 | 
			
		||||
			{
 | 
			
		||||
				if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) // Intentionally not P_TraceWaypointTraversal
 | 
			
		||||
				if (!P_TraceWaypointTraversal(mobj, checkwaypoint->mobj))
 | 
			
		||||
				{
 | 
			
		||||
					// Save sight checks when all of the other checks pass, so we only do it if we have to
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -379,7 +379,7 @@ waypoint_t *K_GetBestWaypointForMobj(mobj_t *const mobj)
 | 
			
		|||
			}
 | 
			
		||||
			else if (checkdist < closestdist && bestfindist == INT32_MAX)
 | 
			
		||||
			{
 | 
			
		||||
				if (!P_TraceBlockingLines(mobj, checkwaypoint->mobj)) // Intentionally not P_TraceWaypointTraversal
 | 
			
		||||
				if (!P_TraceWaypointTraversal(mobj, checkwaypoint->mobj))
 | 
			
		||||
				{
 | 
			
		||||
					// Save sight checks when all of the other checks pass, so we only do it if we have to
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -750,9 +750,6 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
 | 
			
		|||
		if (player->mo->health <= 0)
 | 
			
		||||
			continue; // dead
 | 
			
		||||
 | 
			
		||||
		if (player->bot)
 | 
			
		||||
			continue; // ignore bots
 | 
			
		||||
 | 
			
		||||
		if (dist > 0
 | 
			
		||||
			&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
 | 
			
		||||
			continue; // Too far away
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4538,7 +4538,7 @@ boolean P_SupermanLook4Players(mobj_t *actor)
 | 
			
		|||
	{
 | 
			
		||||
		if (playeringame[c] && !players[c].spectator)
 | 
			
		||||
		{
 | 
			
		||||
			if (!players[c].mo || players[c].bot)
 | 
			
		||||
			if (!players[c].mo)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (players[c].mo->health <= 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -334,6 +334,12 @@ static boolean P_CanTraceBlockingLine(seg_t *seg, divline_t *divl, register los_
 | 
			
		|||
 | 
			
		||||
	(void)divl;
 | 
			
		||||
 | 
			
		||||
	if (!(line->flags & ML_TWOSIDED))
 | 
			
		||||
	{
 | 
			
		||||
		// stop because it is not two sided anyway
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (P_IsLineBlocking(line, los->compareThing) == true)
 | 
			
		||||
	{
 | 
			
		||||
		// This line will always block us
 | 
			
		||||
| 
						 | 
				
			
			@ -380,11 +386,16 @@ static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los
 | 
			
		|||
	if (los->compareThing->player != NULL && los->alreadyHates == false)
 | 
			
		||||
	{
 | 
			
		||||
		// Treat damage sectors like walls, if you're not already in a bad sector.
 | 
			
		||||
		sector_t *front, *back;
 | 
			
		||||
		vertex_t pos;
 | 
			
		||||
 | 
			
		||||
		P_ClosestPointOnLine(los->compareThing->x, los->compareThing->y, line, &pos);
 | 
			
		||||
 | 
			
		||||
		if (K_BotHatesThisSector(los->compareThing->player, line->frontsector, pos.x, pos.y)
 | 
			
		||||
			|| K_BotHatesThisSector(los->compareThing->player, line->backsector, pos.x, pos.y))
 | 
			
		||||
		front = seg->frontsector;
 | 
			
		||||
		back  = seg->backsector;
 | 
			
		||||
 | 
			
		||||
		if (K_BotHatesThisSector(los->compareThing->player, front, pos.x, pos.y)
 | 
			
		||||
			|| K_BotHatesThisSector(los->compareThing->player, back, pos.x, pos.y))
 | 
			
		||||
		{
 | 
			
		||||
			// This line does not block us, but we don't want to be in it.
 | 
			
		||||
			return false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4282,7 +4282,7 @@ boolean P_IsPlayerValid(size_t playernum)
 | 
			
		|||
 | 
			
		||||
boolean P_CanPlayerTrigger(size_t playernum)
 | 
			
		||||
{
 | 
			
		||||
	return P_IsPlayerValid(playernum) && !players[playernum].bot;
 | 
			
		||||
	return P_IsPlayerValid(playernum);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// \todo check continues for proper splitscreen support?
 | 
			
		||||
| 
						 | 
				
			
			@ -4310,7 +4310,7 @@ static void P_ProcessEggCapsule(player_t *player, sector_t *sector)
 | 
			
		|||
	mobj_t *mo2;
 | 
			
		||||
	INT32 i;
 | 
			
		||||
 | 
			
		||||
	if (player->bot || sector->ceilingdata || sector->floordata)
 | 
			
		||||
	if (sector->ceilingdata || sector->floordata)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	// Find the center of the Eggtrap and release all the pretty animals!
 | 
			
		||||
| 
						 | 
				
			
			@ -4517,9 +4517,6 @@ static void P_EvaluateDamageType(player_t *player, sector_t *sector, boolean isT
 | 
			
		|||
 | 
			
		||||
static void P_EvaluateLinedefExecutorTrigger(player_t *player, sector_t *sector, boolean isTouching)
 | 
			
		||||
{
 | 
			
		||||
	if (player->bot)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!sector->triggertag)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue