Jump to content

Improved Bot


Handepsilon
 Share

Recommended Posts

  • Developer

Okay, so I'm working on a more decent bot for RenX.

Current Progress : Currently trying to get them to go disarm beacon when one is spotted.

class Rx_Bot_Extended extends Rx_Bot;

function class BotBuy(Rx_Bot Bot, bool bJustRespawned)
{
local int PickedVehicle;
local int PickedChar;
local class PickedCharClass;
local Rx_PurchaseSystem PurchaseSystem;

PurchaseSystem = Rx_Game(WorldInfo.Game).GetPurchaseSystem();

if(ShouldFindBeacon())
{
		//Single-minded mode, prioritize Beacon first
		`log("Enemy Beacon Detected!!!");
		if(Bot.GetCredits() >= 350)
		PickedChar = 14;
		else
		PickedChar = 4;		
}
else
{
if(Bot.TargetMoney == 0 || (Bot.DeathsTillTargetMoneySwitch == 0 && 

Bot.GetCredits() < Bot.TargetMoney)) {
	Bot.TargetMoney = Bot.GetNewTargetMoney();
	if(FRand() < 0.7) 
		Bot.DeathsTillTargetMoneySwitch = 3;
	else
		Bot.DeathsTillTargetMoneySwitch = 2;		
} 
if(Bot.GetCredits() >= Bot.TargetMoney) {
	PickedVehicle = -1;

	if(Bot.GetOrders() == 'ATTACK' && Bot.GetCredits() >= 350 && !

PurchaseSystem.AreVehiclesDisabled(GetTeamNum(), None) && FRand() <= 0.8) {
		if(Bot.GetTeamNum() == TEAM_GDI) {
			PickedVehicle = GetGdiVehicle();	
		} else {
			PickedVehicle = GetNodVehicle();
		}
	} else 
	if(Bot.GetOrders() == 'DEFEND' && Bot.GetCredits() >= 350 && 

FRand() <= 0.4) {
		PickedChar = 14;	
	} else if(Bot.GetCredits() >= 15000) {
		PickedChar = 4 + Rand(9);	
	} else if(Bot.GetCredits() >= 800) {
		PickedChar = 10 + Rand(3);
	} else if(Bot.GetCredits() >= 800) {
		PickedChar = 7 + Rand(3);
	} else if(Bot.GetCredits() >= 750) {
		PickedChar = 7 + Rand(3);
	} else if(Bot.GetCredits() >= 500) {
		PickedChar = 7 + Rand(3);
	} else if(Bot.GetCredits() >= 225) {
		PickedChar = 4 + Rand(3);
	}

	if(PurchaseSystem.AreHighTierPayClassesDisabled(GetTeamNum())) {
		PickedChar = Rand(4);	
	}

	if(PickedVehicle != -1) {
		if(PurchaseSystem.PurchaseVehicle(Rx_Pri

(Bot.PlayerReplicationInfo), Bot.GetTeamNum(), PickedVehicle)) {	
			Bot.SetBaughtVehicle(PickedVehicle);
			if(Bot.GetCredits() >= 15000) {
				PickedChar = 4 + Rand(9);	
			} else if(!

PurchaseSystem.AreHighTierPayClassesDisabled(GetTeamNum()) && FRand() < 0.25) {
				if(Bot.GetCredits() >= 1000) {
					PickedChar = 10 + Rand(3);	
				} else if(Bot.GetCredits() >= 800) {
					PickedChar = 7 + Rand(3);
				} else if(Bot.GetCredits() >= 750) {
					PickedChar = 7 + Rand(3);
				} else if(Bot.GetCredits() >= 500) {
					PickedChar = 7 + Rand(3);
				} else if(Bot.GetCredits() >= 225) {
					PickedChar = 4 + Rand(3);
				}		
			} else if(FRand() < 0.5) {
				PickedChar = 3;
			}
		}
	} 

	if(PickedChar != 0) {
		if(Bot.GetTeamNum() == TEAM_GDI) {
			PickedCharClass = 

PurchaseSystem.GDIInfantryClasses[PickedChar];
			Rx_Pri(Bot.PlayerReplicationInfo).RemoveCredits

(PurchaseSystem.GDIInfantryPrices[PickedChar]);
		} else {
			PickedCharClass = 

PurchaseSystem.NODInfantryClasses[PickedChar];
			Rx_Pri(Bot.PlayerReplicationInfo).RemoveCredits

(PurchaseSystem.NODInfantryPrices[PickedChar]);
		}
		Bot.TargetMoney = 0;
		`LogRxPub("GAME" `s "Purchase;" `s "character" `s 

PickedCharClass.name `s "by" `s `PlayerLog(Bot.PlayerReplicationInfo));
		return PickedCharClass;
	}
} else if(Bot.GetCredits() > 0) {
	Bot.DeathsTillTargetMoneySwitch--;
} 
}
if(bJustRespawned) {
	return PurchaseSystem.GetStartClass(Bot.Pawn.GetTeamNum());
} else {
	return UTPlayerReplicationInfo

(Bot.PlayerReplicationInfo).CharClassInfo;
}}

function bool AssignSquadResponsibility()
{
if(Rx_Vehicle(Pawn) != None && Enemy != None && !Rx_Vehicle

(Pawn).ValidEnemyForVehicle(Enemy)) {
	//loginternal("LoseEnemy");
	Enemy = None;
	//LoseEnemy();
}	

   if(bStrafingDisabled && Pawn.Anchor == None) {
   	return false;
   }	
if(BaughtVehicleIndex != -1) {
	if(GoToBaughtVehicle()) {
		return true;
	}
} 

if(UTVehicle(Pawn) == None && HasRepairGun()) {
	if(ShouldFindBeacon())
	{
		`log("Enemy Beacon Detected!!!");
		return true;
	}
	if(RepairCloseVehicles()) {
		return true;		
	}
}
return super(UTBot).AssignSquadResponsibility();
}

State Defending
{

Begin:
WaitForLanding();
CampTime = bShortCamp ? 0.3 : 3.0;
bShortCamp = false;
if ( Pawn.bStationary )
{
	Goto('Pausing');
}
SetRouteGoal();
if ( Pawn.ReachedDestination(RouteGoal) )
{
	Goto('Pausing');
}
else
{
Moving:
	Pawn.bWantsToCrouch = false;
	MoveToward(MoveTarget);
	if (Pawn.ReachedDestination(RouteGoal))
	{
		ShouldDefendPosition(); // will change state/label if true
	}
}
LatentWhatToDoNext();
Disarm:
MoveToward(MoveTarget);
if (Pawn.ReachedDestination(RouteGoal))
{
	FireWeaponAt(Focus);	
	`log("Found Enemy Beacon!");
}
if(Focus == None)
GoTo('Begin');
LatentWhatToDoNext();	

Pausing:
if (UTVehicle(Pawn) != None && UTVehicle(Pawn).bShouldLeaveForCombat)
{
	UTVehicle(Pawn).DriverLeave(false);
}

StopMovement();
Pawn.bWantsToCrouch = IsSniping() && !WorldInfo.bUseConsoleInput;
if ( DefensePoint != None )
{
	if ( Pawn.ReachedDestination(DefensePoint) )
	{
		Focus = None;
		SetFocalPoint( Pawn.Location + vector

(DefensePoint.Rotation) * 1000.0 );
	}
}
else if ( (DefensivePosition != None) && Pawn.ReachedDestination

(DefensivePosition) )
{
	SuggestDefenseRotation();
}
SwitchToBestWeapon();
Sleep(0.5);
if (UTWeapon(Pawn.Weapon) != None && UTWeapon

(Pawn.Weapon).ShouldFireWithoutTarget())
	Pawn.BotFire(false);
Sleep(FMax(0.1,CampTime - 0.5));
LatentWhatToDoNext();

}

function bool ShouldFindBeacon()
{
local Rx_Weapon_DeployedBeacon Beacon;

if(Focus.IsA('Rx_Weapon_DeployedBeacon'))
{
	GoToState('Defending','Disarm');
	MoveTarget = FindPathToward(Focus);
	return True;
}

foreach AllActors(class 'Rx_Weapon_DeployedBeacon', Beacon)
{
	if(CheckIfDisarmNeeded(Beacon))
	{
		Focus = Beacon;
		GoToState('Defending','Disarm');
		MoveTarget = FindPathToward(Beacon);
		return True;
	}
}
return false;
}

function bool CheckIfDisarmNeeded(Rx_Weapon_DeployedBeacon DisarmTarget)
{
local RxIfc_SpotMarker SpotMarker;
local Rx_Building TempB;
local float NearestSpotDist;
local RxIfc_SpotMarker NearestSpotMarker;
local float DistToSpot;	

foreach AllActors(class'Rx_Building',TempB,class'RxIfc_SpotMarker')
{
	SpotMarker = RxIfc_SpotMarker(TempB);
	DistToSpot = VSize(TempB.location - location);

	if(NearestSpotDist == 0.0 || DistToSpot < NearestSpotDist) 
	{
		NearestSpotDist = DistToSpot;	
		NearestSpotMarker = SpotMarker;
	}
}

if(Rx_Building(NearestSpotMarker) != None && Rx_Building

(NearestSpotMarker).GetTeamNum() != GetTeamNum())
return True;

return False;

}

I'd love to hear from the AI maker of this game if possible

Current problem...

Beacon planted, some peeps go Engi, but none disarm them

	Rx_GFxHud Transient.Rx_GFxHud_1
Function Renx_Game.Rx_GFxHud:UpdateBuildings:12EB
[1138.55] ScriptWarning: Accessed None 'Icon'
Rx_GFxHud Transient.Rx_GFxHud_1
Function Renx_Game.Rx_GFxHud:UpdateBuildings:12EB
[1138.55] ScriptWarning: Accessed array 'Rx_GFxHud_1.BuildingInfo_Nod' out of bounds (5/5)
Rx_GFxHud Transient.Rx_GFxHud_1
Function Renx_Game.Rx_GFxHud:UpdateBuildings:1414
[1138.55] ScriptWarning: Accessed None 'Stats'
Rx_GFxHud Transient.Rx_GFxHud_1
Function Renx_Game.Rx_GFxHud:UpdateBuildings:1414
[1138.60] Rx: GAME Spawn; player Nod,b271,Elie Arabian character Rx_FamilyInfo_Nod_Soldier
[1138.62] ScriptLog: Enemy Beacon Detected!!!
[1138.64] ScriptWarning: Control reached the end of non-void function (make certain that all paths through the function 'return '
Rx_Bot_Extended uedpiecnc-coastalsmall.TheWorld:PersistentLevel.Rx_Bot_Extended_5
Function renx_extension_ai.Rx_Bot_Extended:ShouldFindBeacon:00CC
[1138.71] ScriptWarning: Accessed array 'Rx_GFxHud_1.BuildingInfo_Nod' out of bounds (5/5)
Rx_GFxHud Transient.Rx_GFxHud_1
Function Renx_Game.Rx_GFxHud:UpdateBuildingInfo_Nod:0027
[1138.71] ScriptWarning: Accessed array 'Rx_GFxHud_1.BuildingInfo_Nod' out of bounds (5/5)

Ignore the non-void function warning. I forgot to put return false at the end of the ShouldFindBeacon function

Link to comment
Share on other sites

Nice initiative! where do you get the time from? I really don't have that many time as you have haha :)

I'd suggest you improve the way the bots handle objective area's, do an analysis of this process as it currently is, then make improvements in it. Maybe bot improvement also means that mappers need to include more area objectives into their map. It might not only be the bot. If they rely on instructions that are (partially) missing than it's up to the mappers to fix that. I'd also suggest looking at the UT3 way of doing paths and setting up area objectives.

Link to comment
Share on other sites

  • Developer

Actually it's just a copy paste. I really don't have that much time, so the progress would be slow indeed. This piece is just to pave path for any dev to include needed feature for the AI

I referenced from the UTBot scripts sometimes but... since I'm not really much of a coder, the whole thing felt so complicated to me.

Link to comment
Share on other sites

Good initiative indeed. Yes AI is a lot of work and as stated before i have no motivation or time to work on the AI anymore. ... dont get me wrong though: If you have the time and interest to work on it it really can be fun. It is an interesting area to work in. And it is rewarding to see them do what you planned them to do.

The RenX Ai is an extension of the UT AI. Thus to "I'd also suggest looking at the UT3 way of doing paths and setting up area objectives." i can reply that its already pretty much done like that as the RenX AI is really just a modified and extended UT3 AI.

Your code modifications so far look good and it looks like youre on the/a right path. I cant spot out the problem immediatly but pls dont expect me/us to go through your AI code and find the problem for you. It can get complicated quickly and thus become hard for us to follow. Instead i could help in getting you an idea how to approach things but you already found a promising approach on beacon disarming. You made a plan, you made the code, but its not working yet. This is what will happen a lot of times when you work on AI. There are a lot of complications in it and so things can go wrong easily. All the AI decission logic needs to fit perfectly together or they will just do something else then what you told them to do. Now the biggest advice i can give you is: Use a debugger. With it you can step through the executed code to find out what the AI is really doing instead of what you planned it to do and why it is making the decission it makes instead of the decissions you planned it to do. And while you watch the code beeing executing in the debugger, trying to find your problem, you will learn a lot about the AI ways of doing things in general.

So you have a plan -> good. You have the code implemented -> good. Not working yet -> ok. Now is the perfect time to fire up a debugger and to take a look at whats really happening.

I spend a lot of time in the debugger to learn how the AI does its things and its the only way i know how to really learn the ways of the UT AI and how to handle its complexity and how to modify it. It would have probably taken me 10x the time to learn about the AI by just reading through the code, using a log output here and there. A debugger really saves you a lot of time on this. There are debuggers built into some Unreal Script IDE´s but personally i use a debugger that is independent/separat from the IDE and just called "unreal debugger" (https://code.google.com/p/unreal-debugger/) and its really easy to use.

Link to comment
Share on other sites

I think we all understand (atleast I do) that you don't have that many time or motivation to do stuff at the moment. Still it is great to see you still support players like this by facilitating them and handing them out tools. Great! Thanks for this.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...