Jump to content


Photo

Attack plan modification


7 replies to this topic

#1 giskard

giskard
  • Members
  • 155 posts

Posted 03 February 2005 - 09:26 PM

Hello all.

Found a very minor change that seems to make the AI attacks a lot more effective. No more peace meal attacks on a small scale.

In \data\ai\plans\attackplan.ai find the following function, should be the first one.

function AttackPlan:__init

change the following

self.num_units = 4

to

self.num_units = 8

Theres a max tolerance setting further down that effects units too but its already set close to the default cap. So i didnt change that. With num_units set the AI appears to attack in greater numbers, though the size varies a little bit sometimes.

I am still testing this my self by so far this one change let the AI wipe out load of my warghbanners and listening posts in my base (which are upgraded to be as tough as marine turrets in my mod).

So im happy so far.

Giskard

#2 Corsix

Corsix

    Code Monkey

  • Hosted
  • 290 posts
  • Location:Berkeley, UK
  • Projects:DoW AI, DoW Mod Studio
  •  Blue Text :)

Posted 03 February 2005 - 09:41 PM

I'm thinking random between small skirmish and large scale attack...
Posted Image

#3 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 03 February 2005 - 09:43 PM

<shutters>

Oh oh.. Big Bad AI not mess'n round here no more..

<fightened>

Wow.. Looks like a picked a wrong time to quit using my training wheels. :sad:

Note to self: Major ass-whopp'n tonight! Ouch....!

Thanks Giskard.. and yes.. randomizing that between 4-8 (or higher) would be most sinister.

Edited by thudo, 03 February 2005 - 09:44 PM.

Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#4 Corsix

Corsix

    Code Monkey

  • Hosted
  • 290 posts
  • Location:Berkeley, UK
  • Projects:DoW AI, DoW Mod Studio
  •  Blue Text :)

Posted 03 February 2005 - 09:55 PM

function AttackPlan:__init( enemy, attack_pos, start_pos, min_units, max_percentage ) super( CpuPlayer.CT_Attacking )



	dbAssert( attack_pos ~= nil )

	dbAssert( start_pos ~= nil )

	dbAssert( enemy ~= nil )

	

	self.attack_pos = attack_pos

	self.gather_pos = Vector3f()

	self.start_pos = start_pos

	self.enemy = enemy

	

	--max percentage of opponents army to attak with

	self.max_percentage = max_percentage 

  

	self:GenerateSafePoint()

	

	Plan.SetNeeds( self, "Obtain Force", AttackPlan.ObtainForce )

	Plan.SetWants( self, "Obtain More Force", AttackPlan.ObtainMoreForce )



	Plan.SetName( self, "Attack Plan" )	



	Plan.SetState( self,  "Gather: <"..string.format( "%.1f", self.gather_pos.x )..","..string.format( "%.1f", self.gather_pos.y )..","..string.format( "%.1f", self.gather_pos.z )..">"..

       	 " Attack: <"..self.attack_pos.x..","..self.attack_pos.y..","..self.attack_pos.z.."> ("..self.enemy:GetPlayerID()..")",

       	 AttackPlan.GatherForces )

	

	cpu_manager:NetSay( 60801, 1, 1.0, true )

	

	self.num_units = math.random(5,9)

	

	--minimum number of units before I can start attacking

	self.min_units = min_units 

	

	self.attack_units = {}

	

	self.timerCaptureFlags = Timer( AttackPlan.ForwardCapture, self, 5 )

	

end

Posted Image

#5 giskard

giskard
  • Members
  • 155 posts

Posted 03 February 2005 - 10:47 PM

Im currently trying to fix the AIs troop choices so expect more on this as i figure more out.

The AI definately seems to use more units its attack with that setting but the unit count seems to include vehicles. So any AI building a lot of vehicles wont include a lot of troops. Which is fine if its land raiders but its just a little warbuggy its not so good.

One word of warning though, that set unit num may be a set once and forget var. So if it chooses a 5 randomly, it may not change it for the next attack. Having said that, every 3rd update its supposed to run the tactics again so it should update it at that time. I think thats in the cpu manager files somewhere.

Giskard

#6 giskard

giskard
  • Members
  • 155 posts

Posted 03 February 2005 - 10:49 PM

Oh nearly forgot, that rating value in unitstats doesnt effect what units it choose.

I set all the ork mobs to the same value and it still picked wildboys, (slugga boys to you).

Edit: Did i say how nasty im feeling towards my mod users at the moment muhaaaa :sad:

Here squiggoth, nice squiggy :sad:

Giskard

Edited by giskard, 03 February 2005 - 10:51 PM.


#7 giskard

giskard
  • Members
  • 155 posts

Posted 04 February 2005 - 01:55 AM

Ok posting this before i forget.

File = data/ai/strategies/buildbasestrategy.ai

This function stops the AI from becoming more powerful than the player.

function BuildBaseStrategy:DoBuildUnits()
	
	--don't go bigger than my opponent's army
	if self.info.max_army_percentage ~= nil then
  local army_cost = self.player_stats:GetArmyCost()
  
  local enemy_army_cost = 0
  
  for player_temp in cpu_manager.stats:GetPlayerStats() do
  	if( cpu_manager.player_stats:IsEnemy( player_temp ) ) then
    local cost = player_temp:GetArmyCost()
    aitrace( "Player "..player_temp:GetPlayerID().." cost: "..cost )
    enemy_army_cost = enemy_army_cost + cost
  	end
  end

  aitrace( "My cost: "..army_cost )
  aitrace( "Max percentage: "..self.info.max_army_percentage*100 )
  aitrace( "Max cost: "..enemy_army_cost*self.info.max_army_percentage )
  

  --don't build units if I'm doing too well
  --must have at least 400 worth of army, though
  if army_cost > 400 and army_cost >= enemy_army_cost*self.info.max_army_percentage then
  	aitrace("too strong: don't build stuff")
  	Tactic.Options.can_reinforce = false
  	
  	--global used to check if I can build anything
  	cpu_manager:SetRestrictMilitary( true )
  	return
  else
  	Tactic.Options.can_reinforce = true
  	cpu_manager:SetRestrictMilitary( false )
  end

	end
	
	--check if using designer strategy. If so, don't build my own units
	if cpu_manager:IsUsingDesignerPreference() then
  aitrace("using designer preferences")
  return
	end

	-- calculate wants for units
	local enemy = cpu_manager:FindClosestEnemyPlayer()
	
	if enemy ~= nil then
  local player_id = enemy:GetPlayerID()
  self:CalculateEffectivenessDemand( player_id )
  self:CalculateClassDemand( player_id )
	end
	
	--need more builder dudes
	self:CalculateEngineerDemand()
	
	profile_start("CalculateDemand")

	for unit_stats in cpu_manager.stats:GetUnitStats( cpu_manager.cpu_player:GetPlayerRace() ) do

  local unit_id = unit_stats:GetID()
  local demand = self:CalculateDemand( unit_id, unit_stats )

  profile_start("SetDemand")
  
  self:SetSquadDemand( unit_id, demand )
  
  profile_end("SetDemand")
  
	end
	
	profile_end("CalculateDemand")
	
	profile_start("BuildStuff")

	local wait = resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Requisition ) < 600 or 
      resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Power ) < 400 
      
	--only build units I can build now if I'm not in second tier, or I'm weaker than opponent (with some buffer)
	if wait and not self:IsInSecondTier() or self.rating < 0 then
  
  aitrace("always building stuff for now")
  self:BuildNow()
  self:BuildLater()
	else
	
  --reset reserve amount
  Tactic.ResourceFloor.requisition = self.info.req_reserve
  
  aitrace("alternate between building stuff now and later")
  
  --reset game timer if needed
  local game_time = cpu_manager.cpu_player:GetGameTime()
  if self.build_now_timer == 0 then
  	self.build_now_timer = game_time
  end
  	
  self.build_now_timer = self.build_now_timer + 1
  
  --figure out ticks passed
  local ticks_passed = game_time - self.build_now_timer
  aitrace( tostring(ticks_passed) )
  
  --call alternately every one minute
  if ticks_passed < 60*8 then
  	aitrace("building stuff for NOW")
  	self:BuildNow()
  else
  	Tactic.ResourceFloor.requisition = 600
  	aitrace("building stuff for LATER")
  	self:BuildLater()
  	if ticks_passed >= 60*8*2 then
    self.build_now_timer = 0
  	end
  end
  
	end
	
	profile_end("BuildStuff")
	
end

In paticular this section.

if army_cost > 400 and army_cost >= enemy_army_cost*self.info.max_army_percentage then
  	aitrace("too strong: don't build stuff")
  	Tactic.Options.can_reinforce = false
  	
  	--global used to check if I can build anything
  	cpu_manager:SetRestrictMilitary( true )
  	return
  else
  	Tactic.Options.can_reinforce = true
  	cpu_manager:SetRestrictMilitary( false )
  end

It gets worse, sort of worse :sad:

Check out the file

data/ai/strategies/advanced/buildbasestrategyinfo.ai

Check the easy, standard and hard too after reading this next bit.

In that file there are several SQUADLIMITS (its an actual var used to choose squad limits per game). The advance file is actually the only one with any variaty at all. The others either have no limits but very restrictive build orders or they only have a "STANDARD" SQUAD LIMIT.

Ok lets go back to the File data/ai/strategies/buildbasestrategy.ai whilst keeping the above file open.

In the.....

function BuildBaseStrategy:__init( baseinfo ) super( baseinfo )

You will see this section.

Quick Note = currently researching Tactic.ResourceFloor.requisition = self.info.req_reserve, seen it tonight, know what it does but cannot remember where.


-- randomly choose one in the set of squad limits

	local count = 0
	for i in self.info.SquadLimits do
  count = count + 1
	end
	
	local rand = math.random( 1, count )
	
	local chosen_strat = nil
	
	--choose the one
	local index = 1
	for i in self.info.SquadLimits do
  if index == rand then
  	chosen_strat = i
  	break
  end
  index = index + 1
	end

Now that piece of code randomly chooses a squad list from the SQUADLIMITS thats set for easy, standard, hard and Advanced difficulty levels.

Combined with the other limits, the AI rarely manages to build everything on that list before he hits the rule, dont become more powerful than the player.

I believe its this rule that causes the AI to suddenly stop doing anything part way through the game for certain players. Its also a good way of creating sets of units to use to attack the player.

EG custom attack waves.

Trouble is, i notice the AI tends to choose one and stick to using that throughout the entire game. I think the reason for this is that this code is placed inside the INI function. Tactics are chosen every 3 updates, which is too often for this kind of change.

Youd need to set it to change roughly every 15 minutes to allow it time to build stuff.

Forgot to mention...

INT_MAX is used to force the AI to always attack when it doesnt have enough units or population to make an effective attack possible.

Giskard

Edited by giskard, 04 February 2005 - 02:03 AM.


#8 giskard

giskard
  • Members
  • 155 posts

Posted 04 February 2005 - 02:57 AM

Ok just a quick note.

The following changes to buildbasestrategy.ai combined with that set.num_units change results in an AI at difficulty Hard that builds a fair sized force, reenforces them all if it has the resources and kicks serious ass :sad:

--don't build units if I'm doing too well
 --must have at least 400 worth of army, though
 if army_cost > 400 and army_cost >= enemy_army_cost*self.info.max_army_percentage then
  aitrace("too strong: don't build stuff")
  Tactic.Options.can_reinforce = true
  
  --global used to check if I can build anything
  cpu_manager:SetRestrictMilitary( false )
  return
 else
  Tactic.Options.can_reinforce = true
  cpu_manager:SetRestrictMilitary( false )
 end

end

Not tested it at easy but there are restrictions in the easy files to stop it getting too far a head of the player. I think its set to only build a force thats 1/3rd the size of the players.

BTW if you randomise the true/false too you can surprise the player 50% of the time :sad:

Giskard

Edited by giskard, 04 February 2005 - 02:59 AM.




Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users