Jump to content


Replying to AI function to attack a specific enemy unit


Post Options

    • Can't make it out? Click here to generate a new image

  or Cancel


Topic Summary

GeorgeSaldana

Posted 15 April 2023 - 07:07 AM

I never tried it before, but after seeing your post. I am thinking about using it. If anyone wants to earn money then I have the best platform for you all. you can visit this website https://bestcasinopl...os/royal-vegas/ where you found the royal vegas gambling site. This is the best online casino venue trusted by many users.


UnsureJedi

Posted 19 March 2023 - 09:01 PM

I see the farseer code, it uses the filter functor to isolate an enemy unit meeting the requirements for the ability and use it if GetClosestSquad() finds the squad meeting the functor. Now, following this example, I just want the farseer to attack the found enemy (I know that in this example the target is friendly but let's suppose its not if I replace GetClosestSquad() with FindClosestEnemy()) instead of performing an ability on him. But I cannot find the DoAttack() function which I would put instead of DoSpecialAbilitySquad() function there. I know there are functions DoMove(), DoAttackMove(), DoStop(), DoRepair(), DoSpecialAbilitySquad(), DoReinforce(), etc., etc., all of which do what it says in the function name. Yet there is no function DoAttack(), or that's what it would be called.

 

I misunderstood your previous post a bit. Of course I won't be searching for specific unit names. That was just the test sample: "tau_ethereal_squad". I've even commented it for myself. I would later replace it with a functor like the one in farseer tactic.


thudo

Posted 19 March 2023 - 08:34 PM

The effectiveness table in the Unitstats.ai DOES NOT tell the AI to specifically target higher value classes, it only gives the AI an incentive to build that specific unit based on the class value so if you give a value of 10 to the Commander class in that table it just incentivizes the AI to build that unit if the enemy has more commander units fielded at the time. Also, its ONLY that first effectiveness line that causes this, the other effectiveness lines are just to incentivize upgrades.

 

If you want the unit to target specific units you need that in the unit's own tactic file BUT its only based on class type that we have that code. ie.. in UA's Eldar Farseer ability we created a tactic for an entity spawned by the Farseer to basically prioritize an array of enemy class types to hunt down assassin-like so you could make a hunter killer-like unit go around and only eliminate builder units OR monsters OR buildings but ONLY based on class_type. You cannot do specific named units per se as what happens when a new faction is introduced: will you keep updating the array forever? Its better to do selective targeting based on class_type so it will always work even with new factions or projects introduced so its adaptive.


UnsureJedi

Posted 19 March 2023 - 04:55 PM

Ok, so I have changed the "commander" effectiveness of assassin's exitus rifle to be higher than all his other effectivenesses and I can say with 100% certainty that it did not work. Here is the assassin field in guardunitstats.ai, where I've changed his commander armor effectiveness to 20.0. And I've also attached the screenshots a moment after the assassin's shot in game: a clean screenshot and with the console open (to see the printed output from the function above). Just as code in the original post was supposed to do, he detected an ethereal (top middle of the screen) in range of 50, activated the scope.... and then shot his bodyguard at the right of the screen, all despite the ethereal being closer and having supposedly higher effectiveness against. Back to square 1, unfortunately.

 

Speaking of targeting enemy units, thudo, isn't this what DoSpecialAbilitySquad() and DoSpecialAbilityEntity() do? They are used by all abilities that require a specific enemy target. For instance, tau commander's "Target Acquired", all of the psyker's abilities and so on, which the AI uses freely. Feels like replacing "do this ability on this target" with "do right-click on this target" (attack this target) should be the simplest of tasks if engine's source code was available. Feels weird why wasn't it implemented initially. Oh well.

{
		name = "Assassin",
		sbp_name = "guard_squad_assassin",
		ebp_name = "guard_leaders_assassin",
		class = UnitStatsAI.UC_Commander,
		rating = 7,
		potential =
		{
			{
				name = "guard_exitus_rifle",
				effectiveness = GenerateUnitEffectiveness(8.6,8.6,8.6,8.6,8.6,5.4,5.4,5.3,8.6,7.4,20.0,0.4,0.7,0.0,0.0,0.0,0.0),
				range = UnitStatsAI.RT_Ranged,
			},
			{
				name = "guard_exitus_pistol_assassin",
				effectiveness = GenerateUnitEffectiveness(7.6,8.1,7.9,7.9,7.1,4.5,4.8,0.0,7.7,0.0,6.7,7.9,6.6,5.8,0.0,0.0,0.0),
				range = UnitStatsAI.RT_Melee,
			},
		}
	},

thudo

Posted 18 March 2023 - 11:59 PM

Sure.. you can target your own entities in your own faction but NOT others as those can be an infinity # hence why for only enemies you must use generic classes - no other way. .

 

 


UnsureJedi

Posted 18 March 2023 - 10:44 PM

Hi! Thanks for the hint! Indeed prioritizing the targets by their armor type (class) could be a workaround. I understand that units choose targets they are more effective against if left on their own in battle.
 
The following is my speculation, and I might be off the point here. I now looked at race loader (loader.ai) more closely and I see there is a "table.insert(UnitStats, GuardUnitStats)" (in case of imperial guard loader). The GuardUnitStats in turn is filled in guardunitstats.ai where among other data the "effectiveness" field is defined, which should be the given unit's effectiveness vs every armor type (class). The UnitStats table is only referenced in cpumanager.ai (function LoadUnitStats()). The LoadUnitStats() is not defined anywhere in dowai so I assume it and hence UnitStats are then used by the DOW engine itself? If so can UnitStats contents be changed midgame and have an immediate effect? I'm not yet fully acquainted with how "table" indexing works, so would accessing, say, "infantry low" effectiveness from UnitStats look like this: UnitStats[<race_index>][<unit_index + 1>][7][<weapon_index>][2][1]? Then, If I want to apply the changes I made to it I need to call LoadUnitStats(UnitStats) again. So by doing this I can change a unit's target priority midgame, when they have multiple enemies to choose from to attack. The problem I see here is huge overhead to call LoadUnitStats() every time a single effectiveness needs to be changed.
 
Again, I might be wrong here and to avoid the headache of this it might just be better to set the assassin's "commander" armor effectiveness to a higher value than all his other types of effectiveness and be done with it. Would that make it prioritize commander armor every time? I will test it tomorrow. 

thudo

Posted 18 March 2023 - 08:37 PM

Afternoon.. its great to see others interested in improving the DoW1 AI.. we always need new devs to come on-board and help.

 

So the AttackMove was decided on a looonng time ago as a compromise when switching parts of a map. It generally works "as is" but yes it can be optimized.

 

As for selecting X or Y squads.. well you can only choose class types like HeavyInfantryMed or Commander or BuildingMed, etc and NOT specifically named targets as those can be anything for infinite mods.

 

e.

 


UnsureJedi

Posted 18 March 2023 - 06:11 PM

Hello. I've recently got involved into refining the skirmish AI 3.2, improving races that are consistently losing against space marines and tau (these have shown to be the best) in 1v1. I've made a lot of progress with improving the build orders, tactics, ability usage and fixed a couple of bugs.
However, a big obstacle has come up which I did not expect to exist: there is no way that I see for the AI to tell one of its squads to attack a specific enemy squad or building. There are plenty of examples where this would be useful, I will post one: I want vindicare assassins to prioritize commander units when they show up in assassin's firing range. Here is the DoAbilities() function that would do this if I could replace DoAttackMove(vTargetPos) with something like DoAttack(oEnemy). As far as I know the DoAttack() function, or one like it, simply does not exist. The AI can only attack with attack moves which really surprised me, since players can just right click the enemy to attack. Can anyone help?

function AssassinTactic:DoAbilities()
	print(self.squad_ai:GetSquadName() .. " is checking for commanders in range of assassination scope")
	
	local oFunctor = function(oSquad)
		return (oSquad:GetSquadName() == "tau_ethereal_squad")    -- Just check for tau_ethereal_squad for now
	end		
			
	local oEnemy = cpu_manager:FindClosestEnemy(self.squad_ai:GetPosition(), 50, oFunctor)
	if (oEnemy ~= nil) then
		print("Found a squad " .. oEnemy:GetSquadName())
		if (self.squad_ai:CanDoAbility(Assassin.assassinate_id)) then	
			print("Found a squad " .. oEnemy:GetSquadName() .. " Activating assassination scope.")		
			Ability.DoAbility( self.squad_ai, Assassin.assassinate_id, Ability.PredicateFilters.ConstantTrue)
		end
		local vEnemyPos = oEnemy:GetPosition()
		local vTargetPos = Vector3f(vEnemyPos)
		    
		--cpu_manager:DoMove(self.squad_ai, vTargetPos, true, "Attacking")
		self.squad_ai:DoAttackMove( vTargetPos )	-- This command indeed just attack moves to target so it does not guarantee that this specific target will be shot
	end
end

Review the complete topic (launches new window)