Jump to content


Photo

Dawn Of Skirmish SS v3.10 AI Mod is now LIVE!


80 replies to this topic

#41 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 25 April 2009 - 06:46 AM

The code segment starts with elseif (sType == "Unit") then. Therefore it's only computed if the build controller checks a unit build item and not enough units of this type are on the field. If the build controller gets stuck because of this, then there are three possibilities:

1.) The unit can't be built because the necessary building or tech is not available or...

2.) The name of the unit is written incorrect and the build controller can't find any buildings where he can build the unit.

3.) The units are part of a rush program. In this case no other units are built until the rush is over. (If I remenber right...)

If those don't apply, it's possible that there's a completely other reason for the problem.


Thanks for clarification, Arkhan. Will check for different reasons in my code.

I have a suggestion I use for CC commanders with DowPro AI. I changed ChekForDetach() to

function InfantryTactic:CheckForDetach()

	-- Set detach health
	local fDetachHealth = self.m_fCommanderAttachHealth + 0.2

	-- Detach healthy commanders after combat.
	if (not self.squad_ai:IsInCombat() and not self.squad_ai:WasRecentlyHurt() and
		self:CommanderAttached() and self.squad_ai:GetAttachedHealthPercentage() > fDetachHealth) then
		self.squad_ai:DoDetachSquad()
		self.squad_ai:DoSetDefaultMeleeStance()
	end
	
	-- Detach commander from broken/capturing
	if ((self.squad_ai:IsBroken() or self.squad_ai:IsCapturing()) and
		(self.squad_ai:IsInCombat() or self.squad_ai:WasRecentlyHurt())) then 
		
		self.squad_ai:DoDetachSquad()
		self.squad_ai:DoSetDefaultMeleeStance()
	end
end


and the attach code for CC commanders (expl. farseer) to

-- Assassinate win condition -- never attach to a squad / do not attach while dancing
	if (not cpu_manager.assassinate and self.squad_ai:GetMeleeStance() == SquadAI.MSTANCE_Assault) then		  
		if (self.squad_ai:IsInCombat() or self.squad_ai:WasRecentlyHurt()) then
			if (self:TryAttachSquad(false, true, 50, 150, self.m_fCommanderAttachHealth) == nil) then


				self:TryAttachSquadMelee()
			end
		end
	end

What's the difference to the old code ? The CC commander will not attach to CC squads by default but only in combat with self:TryAttachSquadMelee() if one is nearby and detach afterwards if out of combat. This will a) increase the chance to fight independantly and to tie up more ranged squads and b) release the comander to act independantly after combat if healthy. This will prevent the attached farseer fleet of foot bug too. He/she will still attach to ranged if hurt.

#42 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 25 April 2009 - 06:50 AM

Arkhan can you tell me the reason for the new workaround squad cap code ?

#43 ArkhanTheBlack

ArkhanTheBlack

    title available

  • Members
  • 814 posts

Posted 25 April 2009 - 09:06 AM

I have a suggestion I use for CC commanders with DowPro AI. I changed ChekForDetach() to

Sounds good! Done!


and the attach code for CC commanders (expl. farseer) to

Also done! (Just for farseer if I understood right?!)


Arkhan can you tell me the reason for the new workaround squad cap code ?

Relic broke another of the squad cap calculation routines in SS. Before, I think only squadcapmax could get screwed up. But in SS another one can also get messed up (squadcap or currentsquadcap, not sure anymore). Therefore I had to rewrite the code and include some security checks. I can asure you that I wasn't exactly thrilled to be forced to rewrite that code :p .

#44 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 25 April 2009 - 09:24 AM

New attach/detach code is not only usable by farseer but all CC commanders. Farseer is most usefull though as it reduces the fof problem.

Question : Isn't MinArmyStrength superfluous as we already have MinArmyStrengthPerTier ?

AttackStrategyInfo = 
{	
	tau_race =
	{
		MinArmyStrength = 750,
	},
}


#45 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 25 April 2009 - 09:27 AM

I'd like to to see

-- Check if Relic is required
	 if (not self:HasRelic() and self:RelicRequired(sName)) then
		 return
	 end

added for all the DynamicXYZ() (Research, Unit, Addon) functions in buildbasestrategy.ai. I did add this for Pro AI but prefer not to deviate to much from skirmish mode core code.


Bump.

#46 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 25 April 2009 - 10:08 PM

Relic broke another of the squad cap calculation routines in SS.


How ? I did not encounter any problems yet with DoWpro.

#47 ArkhanTheBlack

ArkhanTheBlack

    title available

  • Members
  • 814 posts

Posted 26 April 2009 - 09:54 AM

Question : Isn't MinArmyStrength superfluous as we already have MinArmyStrengthPerTier ?

No, the MinArmyStrength for a T1 army is usually higher than the army size increases per tier.


added for all the DynamicXYZ() (Research, Unit, Addon) functions in buildbasestrategy.ai. I did add this for Pro AI but prefer not to deviate to much from skirmish mode core code.

Yes, I can do that.


How ? I did not encounter any problems yet with DoWpro.

If I remember right the AI didn't build anymore units because it thought that the squad cap is full. The squad cap function returned a value of several millions or more and screwed up the whole unit building management. It doesn't happen all the time and I don't know what causes it.

#48 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 27 April 2009 - 10:58 AM

I'm a bit confused about DoAbilities.

If I check BansheeTactic:DoAbilities() for example it is not calling the basic EldarInfantryTactic:DoAbilities()
Therefore attached farseer will not use her abilities. This is a bug, isn't it ? Some squads use their own specific DoAbilities() but do not call for their RaceXYZInfantryTactic:DoAbilities(), ignoring the abilities of attached units. Bug or misunderstanding on my part ?

Edited by LarkinVB, 27 April 2009 - 11:49 AM.


#49 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 27 April 2009 - 05:04 PM

CheckSquadCap and CheckSupportCap can cause problems. The function will SaveResources before checking wether threshhold is reached at all. The checks should be switched, first threshhold, than resources. It caused some headache with DoWPro.

-- Arkhan 10.2005: Calculates, if more squad cap is needed
function BuildBaseStrategy:CheckSquadCap(iMinRequisition, iMinPower)

	-- Check requisition
	local iRequisition = resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Requisition ) / self.m_iTechBreak
	local iPower = resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Power ) / self.m_iTechBreak
	if (iRequisition < iMinRequisition or iPower < iMinPower) then
		self:SaveRessources(true)
		return false
	end
	
	-- Check squad cap
	local iSquadCapTotalMax		= build_manager:GetSquadCapTotalMax()
	local iSquadCapLeft			= self:GetSquadCapLeft()
	local iSquadCapCurrentMax	= self:GetSquadCap() + iSquadCapLeft
	if (iSquadCapLeft <= self.info.squad_cap_threshold and iSquadCapCurrentMax < iSquadCapTotalMax) then
		return true
	end
	
	return false
end


#50 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 28 April 2009 - 05:20 AM

Question 1: If I have expensive researches/units in build order like

{ 3,	650,	750,	3000,	1,	"Research",		"chaos_bloodthirster_research" },

SaveResources() will kick in, right ? Isn't HasResourceOverflow() with its lower requirements (800 req, 500 power) preventing the process of saving up ? I think this is a bug.

Question 2: AI had 2 builders in allied hq and 210 req. The HQ was destroyed and listed at the top of the build order (cost 200 req). Nevertheless the builders did not start to build an new HQ and the AI was killed afterwards. Why didn't they build the new HQ ?

#51 ArkhanTheBlack

ArkhanTheBlack

    title available

  • Members
  • 814 posts

Posted 28 April 2009 - 11:46 AM

If I check BansheeTactic:DoAbilities() for example it is not calling the basic EldarInfantryTactic:DoAbilities()
Therefore attached farseer will not use her abilities. This is a bug, isn't it ?

Yes, I think so. Though I'd call it more an omission than a bug.


Some squads use their own specific DoAbilities() but do not call for their RaceXYZInfantryTactic:DoAbilities(), ignoring the abilities of attached units. Bug or misunderstanding on my part ?

If a commander can attach to the squad, then it's probably also a bug.


CheckSquadCap and CheckSupportCap can cause problems. The function will SaveResources before checking wether threshhold is reached at all. The checks should be switched, first threshhold, than resources. It caused some headache with DoWPro.

Have to check that out at home. To be honest I can't remember the resource check at all...


SaveResources() will kick in, right ?

Yes, if the AI has an army worth 3000, it will save ressources for the build item.


Isn't HasResourceOverflow() with its lower requirements (800 req, 500 power) preventing the process of saving up ? I think this is a bug.

It's the default value. If the race has more expensive build items the function has to be overwritten. That should be the case for Necrons in vanilla SS. I think all other races in vanilla SS are fine with that values.


Question 2: AI had 2 builders in allied hq and 210 req. The HQ was destroyed and listed at the top of the build order (cost 200 req). Nevertheless the builders did not start to build an new HQ and the AI was killed afterwards. Why didn't they build the new HQ ?

Yes, I've seen that too. I investigated the problem some time ago and I think the build plan was generated, but the builders didn't find a place or free way to build it. It was a bit...odd. I'm pretty sure it's a problem of the build plan and not the build controller.

#52 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 29 April 2009 - 10:52 AM

Thanks for clarification.

More problems. Ability.DoAbilityArea and possibly other abilities are not handled right sometimes. Check the code below. The coder is using the last number as if it is the threshold of units to trigger but in fact it is the range. It makes no sense to reduce range in case the unit is dying.

function SistersCanonessTactic:DoAbilities()

	-- reduces enemy weapon accuracy and increases own weapon damage (Faith cost: 30)
	Ability.DoAbilityArea( self.squad_ai, SistersCanoness.divinelight_id, Ability.Filters.CloseEnemy, 8 )

	-- summons non-player controlled angels to fight for a short period (Faith cost: 90)
	Ability.DoAbilityArea( self.squad_ai, SistersCanoness.ascension_id, Ability.Filters.CloseEnemy, 10 )

	-- We are dying, lower requisites for attacks
	if (self.squad_ai:WasRecentlyHurt() and self.squad_ai:GetHealthPercentage() < 0.4) then
		Ability.DoAbilityArea( self.squad_ai, SistersCanoness.divinelight_id, Ability.Filters.CloseEnemy, 4 )
		Ability.DoAbilityArea( self.squad_ai, SistersCanoness.ascension_id, Ability.Filters.CloseEnemy, 5 )
	end
end

Edited by LarkinVB, 29 April 2009 - 10:53 AM.


#53 thudo

thudo

    Wacko AI Guy!

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

Posted 29 April 2009 - 01:55 PM

What? Thats the way we've done it for almost all such abilities since the beginning. The only exception is the Banshee's Warp Scream and perhaps some others.
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#54 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 29 April 2009 - 03:09 PM

Regardless wether it was handled so since the beginning (I doubt this) it is faulty.

DoAbilityArea = function( squad_ai, id, functor, range, threshold )

Parameter 4 is range, parameter 5 is threshold which is 1 in case of nil, therefore

Ability.DoAbilityArea( self.squad_ai, SistersCanoness.divinelight_id, Ability.Filters.CloseEnemy, 8 )

is using the ability in range 8, threshold 1. I'm pretty sure this was not intended. Especially not if you look at the code while the canoness is hurt :

Ability.DoAbilityArea( self.squad_ai, SistersCanoness.divinelight_id, Ability.Filters.CloseEnemy, 4 )

Now the range is reduced to 4, so it is even more unlikely it will be used.

#55 thudo

thudo

    Wacko AI Guy!

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

Posted 29 April 2009 - 03:11 PM

No no.. very good observation.. easy fixes of course but wow.. odd that we scripted the Banshee War Scream just fine but then failed on others that use the same Ability filter.
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#56 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 29 April 2009 - 06:54 PM

More problems with abilities.ai :

1. First the Filters using iCount within won't work as expected and should be removed or reworked.
That is CloseInfiltrator, CloseBroken, CloseInfantryEnemyCC, CloseVehicleHighEnemy, CloseMonsterHighEnemy, CloseMonsterEnemy

CloseInfiltrator is even missing the iCount ~ nil check and can crash the AI.
All of them won't work as iCount will always be nil, therefore returning nil for all checks. I'm aware that they are usually not used any longer but AI coders not aware of their brokeness may try to make use of them as KaiserSoze tried while coding DoWPro AI.

2. Why is CloseSquadEnemy = function( position, tolerance, count ) using an additional check for 4 troopers, rendering the count parameter useless ?

#57 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 30 April 2009 - 10:42 AM

Even more problems with DoAbilities().

DoPossess() is called in InfantryTactic but chaos lord is not using this. Is this intentional ? I guess he won't morph into daemonprince because of this, right ?

#58 thudo

thudo

    Wacko AI Guy!

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

Posted 30 April 2009 - 01:57 PM

- DoAbilityArea - Larkin, does your suggestions ONLY affect abilities that use DoAbiliityArea ? I am assuming so and its an easy fix to work each area ability based on the Banshee War Scream.

- DoPossess() -- yes this does work with our current SS AI build **BUT** the AI is almost always slow to use it. It can take minutes before the AI actually causes the Lord to become the DP or a Marine Sarg to be the BT. The easy fix? Just force DoPossess() in the unit's tactic file to use it when it combat similar to the old Necron Lord script we used before SS screwed up that code (due to no function to allow an AI to know how to go between to possession possibilities: NightBringer or Deceiver). So when you force DoPossess() in a unit's tactic file when in combat it always works 100% fast.
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#59 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 30 April 2009 - 10:23 PM

So when you force DoPossess() in a unit's tactic file when in combat it always works 100% fast.


This does not make sense. If the InfantryTactic.DoAbilities is called correctly it should work as fast as if called by a squads tactic.

To be honest I don't see how the lord could mutate to prince at all. He does not call DoPossess().

Edited by LarkinVB, 30 April 2009 - 10:33 PM.


#60 thudo

thudo

    Wacko AI Guy!

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

Posted 01 May 2009 - 01:59 AM

Actually yes he does.. its in the Chaos Lord's ebps code:

GameData["possess_ext"]["requirements"] = Reference([[tables\requirements.lua]])
GameData["possess_ext"]["requirements"]["required_1"] = Reference([[requirements\required_research.lua]])
GameData["possess_ext"]["requirements"]["required_1"]["hide_the_button_when_failed"] = false
GameData["possess_ext"]["requirements"]["required_1"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_1"]["research_must_not_be_complete"] = false
GameData["possess_ext"]["requirements"]["required_1"]["research_name"] = "research\\chaos_daemon_prince_research.lua"
GameData["possess_ext"]["requirements"]["required_10"] = Reference([[requirements\required_structure.lua]])
GameData["possess_ext"]["requirements"]["required_10"]["is_display_requirement"] = true
GameData["possess_ext"]["requirements"]["required_10"]["structure_name"] = "ebps\\races\\chaos\\structures\\chaos_hq.lua"
GameData["possess_ext"]["requirements"]["required_11"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_11"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_2"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_2"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_3"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_3"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_4"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_4"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_5"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_5"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_6"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_6"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_7"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_7"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_8"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_8"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_9"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_9"]["is_display_requirement"] = false
GameData["possess_ext"]["research_to_revert"] = "chaos_daemon_prince_research"
GameData["possess_ext"]["show_possession_ui_button"] = true
GameData["possess_ext"]["squad_replacement_name"] = "chaos_squad_daemon_prince"
That was introduced in Dark Crusade. Its the same exact code as the Necron Lord uses:

GameData["possess_ext"]["requirements"] = Reference([[tables\requirements.lua]])
GameData["possess_ext"]["requirements"]["required_1"] = Reference([[requirements\required_research.lua]])
GameData["possess_ext"]["requirements"]["required_1"]["hide_the_button_when_failed"] = false
GameData["possess_ext"]["requirements"]["required_1"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_1"]["research_must_not_be_complete"] = false
GameData["possess_ext"]["requirements"]["required_1"]["research_name"] = "research\\necron_ctan_research.lua"
GameData["possess_ext"]["requirements"]["required_10"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_10"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_11"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_11"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_2"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_2"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_3"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_3"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_4"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_4"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_5"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_5"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_6"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_6"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_7"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_7"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_8"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_8"]["is_display_requirement"] = false
GameData["possess_ext"]["requirements"]["required_9"] = Reference([[requirements\required_none.lua]])
GameData["possess_ext"]["requirements"]["required_9"]["is_display_requirement"] = false
GameData["possess_ext"]["research_to_revert"] = ""
GameData["possess_ext"]["show_possession_ui_button"] = true
GameData["possess_ext"]["squad_replacement_name"] = ""
GameData["possess_ext"]["squad_replacement2_name"] = "necron_night_bringer"
GameData["possess_ext"]["squad_replacement3_name"] = "necron_deceiver_squad"
There are a few user faction mods that used this code for a while and using the DoPossess as follows in their tactic file:

function DeathGuardLordTactic:DoAbilities()

	-- Try to possess and become Daemon Prince
	if (self.squad_ai:IsInCombat() and self.squad_ai:CanPossess()) then
		self.squad_ai:DoPossess()
	end
This is the code Arkhan used for the NL back in DarkCrusade before Relic screwed it due to not having exported function for DoPossess() when the user has 2 options for a possession rather than just one. The above code works 100% more reliably and causes the AI to immediately possess a unit when the prereqs are satisfied (and in combat).
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!



Reply to this topic



  


2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users