Commander Attachment AI
#1
Posted 01 March 2006 - 03:15 AM
How does the AI know when to attach things? How does it deattach? A quick lesson for us all...
Firstly, certain things run on a squad. A squad is each seperate entity on the battlefield which can be selected.
This was my first hurdle of understanding, that, in fact, commanders when attached cannot be got at except through a few info functions such as GetAttachedHealthPercentage() and an important HasSquadAttached().
So, when a squad has a commander attach, the squad's AI determines when the commander de-attaches.
Also, this means we cannot check stat info of the attached unit, since they are not a seperate squad, they don't have gettable names, stats (eg: ranged, stances) or suchlike.
-------------
There are some additional problems with the AI code. Namely, some useful information, such as if a unit is unbreakable, are unavailable (things like squad size, "rating" and suchlike are available). A shame.
-------------
So this is what I'm working on:
- A table set via. the squad's ID, when they are attached to by a commander unit, with ranged and stance information, as well as a special field "keep_attached", which if true, will never deattach the unit.
- An additional (table) input for TryAttachSquad(), called something like best_attach_unit. Possibly the table will include some stats to check for, or requirements for attaching to the best squad. Range limits still apply of course. This code would allow the farseer to attach (permanently) to seer councils, for instance. Will get this table to be priority based - possessed marines over khorne beserkers for instance.
- Will add a way to make sure units stay attached to a commander for a greater amount of time. Units attaching then suddenly detaching just because the current battle is over is counter productive sometimes.
- Might detach during combat, need to look into switching to a really close, better CC squad if the commander is in CC.
- Will attach some ranged heroes to ranged squads mostly permanently (eg: Sorceror, who is a bit weak in CC)
- Broken squads will not automatically get deattached, since the commander might just be better off staying with them for a few more seconds (especially with space marines).
- Only named, primary heroes (in the exsisting hero table to be precise) would have permanent fixtures applied.
- Might attach melee commanders to (primarily) ranged (but still good/mediocre in CC) units if there are a few around, to provide some cover for the commander (eg: Space Marines, Chaos Space Marines, Cultists, Shootas, Guardians).
- Might attach ranged commanders to primarily melee units, and set the squad to range, if there are a lot of them. For example, Khorne Beserkers do have pistols, as well as Banshee's, Sluggas, Nobz, etc. Could happen when damaged (it was meant to according to the code before anyway), but this might happen before combat.
- TryAttachSquadMelee() should be revamped to allow a commander to look for specific squads first.
Perhaps most importantly, besides the permanent fixtures mentioned:
- Commanders might well attach well before combat with good or large units, meaning they are ready with a good unit as cannon fodder/backup right away and provide bonuses before hitting enemy units. Also groups commanders with the army better.
---------------------
I will post code changes later if I can get some of the stuff working well. It'd mean changes to each commander's specific AI files, but that'd not matter too much.
I will look into the tables info, and see if some decent logic can be decided on how commanders attach to units and how they deattach according to conditions.
Will also see if we can have the race code "race"infantrytatics.ai file, return "moraleimmune" function as true if an actual unbreakable unit (EG: Khorne Beserkers).
A lot to do? not much, to long winded. Any suggestions on how you attach commanders, and how the AI should, would be welcome. Might as well get it right first time.
#4
Posted 01 March 2006 - 01:23 PM
Is there a good way to check if the squad or commander is in an attack run? (they are obviously not attacking otherwise). If there is a good way, I'll add in code for commanders to possibly find a decent squad to attach to for the duration of the attack.
#7
Posted 12 March 2006 - 01:53 PM
Infantry tatic.ai changes:
-- FD additional code -- This table holds information on the commander attached to us, and if they want to stay attached. InfantryTactic.AttachedInfo = {}
-- FD: Returns true if we have a specific hero attached - ie: Force Commander, Librarian, never Apothecary. function InfantryTactic:CommanderAttached() if self.squad_ai:IsAttached() then for i in self.commander do if self.squad_ai:HasSquadAttached( self.commander[i][1] ) then return true end end end return false end --[[ Finaldeath: Need to rework. This is called each update call, on squads with commanders attached to them. Will: - Detach a healthy commander unit if squad is now not in combat and not recently hurt. - Will not detach dying (<50% health) heroes - Will not detach ranged heroes if a ranged squad If detached: - Sets stance back to default (eg: get a melee hero attached to a ranged squad, and was melee stance, will now set back to ranged stance) Changes: - Keep some squads always attached - Farseer + Seer council - Terminators + Force commander etc. - Possibly detach a commander in combat if there is a better squad they could attach too? Useful functions: - float GetAttachedHealthPercentage(void) - bool HasSquadAttached( const char* squad_name ) Can check for specific commanders attached to us. ]] function InfantryTactic:CheckForDetach() --print("InfantryTactic:CheckForDetach FOR: "..self.stats:GetSquadName() ) -- FD: New code -- Match such as GetID() of the squad, and the unit we have got attached to us. -- The table array InfantryTactic.AttachedInfo[our_id][INFONAME] contains extra info about why the commander attached -- and what the commander is like. local our_id = self.stats:GetID() -- Get commander attached to us. Might be an empty string if not a primay commander attached to us. local commandername = self:GetNameOfAttachedCommander() -- FD: Will not detach if we have not reached time limit if( cpu_manager.cpu_player:GetGameTime() < InfantryTactic.AttachedInfo[our_id]["time_limit"] ) then --print("InfantryTactic:CheckForDetach | IGNORING: Not reached time yet | us: "..self.stats:GetSquadName()..": attached name (might be invalid): "..commandername) return nil end -- FD: Will not detach if we are: -- - In combat -- - Being attacked -- - Attacking someone if( self.squad_ai:IsInStateAttackMove() or self.squad_ai:IsInCombat() or self.squad_ai:WasRecentlyHurt() ) then -- Do no switching in combat or when taking damage --print("InfantryTactic:CheckForDetach | IGNORING | us: "..self.stats:GetSquadName()..": attached name (might be invalid): "..commandername) return nil end -- Check if we have a primary commander attached. Means a valid commandername field. if commandername == "" then -- No *primary* commander attached, we therefore ignore more checks FOR NOW. return nil end -- If we find that we want to stay attached dispite time... if( commandername == InfantryTactic.AttachedInfo[our_id]["commander"] and InfantryTactic.AttachedInfo[our_id]["keep_attached"] == true) then -- We want to stay attached, but is there another (better) unit nearby this commander would attach to? -- FD: TODO based on InfantryTactic.AttachedInfo[our_id]["best_attach_units"] table -- ...we want to keep this commander attached forever, nevermind morale, health or otherwise. return nil end -- FD: Will detach if we are healthy -- OR we are a melee squad (ranged squads wait for the 50% health theshold, but if damaged and in a melee squad, -- commanders should not get involved in melee!) if( self.squad_ai:GetAttachedHealthPercentage() > 0.5 or not self.squad_ai:IsRanged() ) then -- Are we broken? (at the moment) always detach if ( self.squad_ai:IsBroken() ) then -- Detach self:DetachOurAttachment() return nil end -- Are we capturing something? always detach if healthy/melee if ( self.squad_ai:IsCapturing() ) then -- Detach self:DetachOurAttachment() return nil end -- If melee unit then we will detach if our commander isn't melee if ( not self.squad_ai:IsRanged() and InfantryTactic.AttachedInfo[our_id]["is_ranged"] == true ) then -- Detach self:DetachOurAttachment() return nil end end return nil -- FD: Old code --[[ -- If not in combat and not recently hurt if (not self.squad_ai:IsInCombat() and not self.squad_ai:WasRecentlyHurt()) then -- We will detach healthy commanders, with 50% or more health. -- Any ranged units will not detach commanders from them. if (self:CommanderAttached() and (self.squad_ai:GetAttachedHealthPercentage() > 0.5 or not self.squad_ai:IsRanged())) then self.squad_ai:DoDetachSquad() self.squad_ai:DoSetDefaultMeleeStance() end end ]] end -- FD: Wrapper function, -- No way to delete hashed table entries. This might do something with the table (like "clear the entry") perhaps however. function InfantryTactic:DetachOurAttachment() print("InfantryTactic:DetachOurAttachment | us: "..self.stats:GetSquadName()..": attached name (might be invalid): "..self:GetNameOfAttachedCommander()) -- Do the detachment self.squad_ai:DoDetachSquad() self.squad_ai:DoSetDefaultMeleeStance() end -- FD: This will return the unit name who is attached to us function InfantryTactic:GetNameOfAttachedCommander() if self.squad_ai:IsAttached() then for i in self.commander do if self.squad_ai:HasSquadAttached( self.commander[i][1] ) then return self.commander[i][1] end end end -- Return empty string on none return "" end
Tatic.ai changes:
--[[ How this works: - This is called from commander's tatic files. - Then, once attached, cannot be called again (they are part of a new squad). - When attached to a squad, that squad will call CheckForDetach() Attempts to attach us to a squad. TryAttachSquad ( melee, match_stance, radius, min_strength, health ) melee - If TRUE we attach to melee squads primarily, if FALSE we attach to ranged squads first. melee_stance - If TRUE we must attach to the value above. If FALSE, we will use the other option as a secondary option. radius - Distance we can attach to squads in meters min_strength - Minimum squad strength to attach too health - the % health we should be at to attach TryAttachAssassinate() Will always attempt an attach with anything nearby to survive. TryAttachSquadMelee() Will attach to squads within 10M if in combat. See also: InfantryTactic:CheckForDetach Will *detach* unless a ranged attachable unit (which is set on all things like apothecarys, commissars, etc) - Need to also sort eg: -- force commander --assassinate win condition -- always attach to a squad if cpu_manager.assassinate then self:TryAttachAssassinate() else --state machine if not InfantryTactic.Update( self ) then return end if self:TryAttachSquad( false, true, 50, nil, 0.4 ) == nil then self:TryAttachSquadMelee() end end -- librarian if self:TryAttachSquad( false, true, 50, nil, 0.5 ) == nil then self:TryAttachSquadMelee() end --apothecary self:TryAttachSquad( false, false, 1000, 250, nil ) Need revamping Possible ideas: - Add in morale stats to all units. Units who are immune to morale damage can get attached to. - Attach always to high rated units nearby. - Always attach to benificial/prefered units - Farseer + Seer Council (Possibly Banshees, gains spell time decrease from seer council) - Force Commander, Librarian + Terminators (Possibly only assault ones) - Chaos Lord + Possessed Space Marines, Khorne Beserkers (Morale immunity, Melee orientated) - Sorceror + Marines, Possed, Beskerkers. (Maybe more of a ranged hero? Morale immunity is good though) - Warboss or Warboss + Nobz, Sluggas (Group ork bonuses, waagh power, teleporter, cannon fodder) - (does this already) Any IG secondary hero, apothecarys, bad doks - always attach! - Stay attached for a minimum amount of time - Attach if we are very near to a matching stance squad and are in combat anyway. - Do not deattach if on a broken squad. Usually this hinders morale regen since the commander and squad can be hit seperately. AIMS: - Attach some commanders much more early then combat situations and stay together - Especially with Farseer, etc. - Late game, always attach early (since most commanders die quite fast otherwise) - Squads with commanders should reinforce more - Can attach to morale immune squads to gain benifit if broken - Do not keep switching squads in combat unless really good one is nearby. - Some heroes should properly attach to ranged squads as a preference to melee squads, and not change the stance of the squad to melee (eg: sorceror, librarian with word of the emporer, farseer with spells or low health). - If at low HP, will attach to a ranged squad to recover health, and stay at ranged stance. Useful functions: - bool IsAttached( Void ) - function CpuManager:GetClosestSquad( pos, range, functor ) NB: The function GetClosestSquad() isn't going to be too good for getting the best general unit to attach to in combat. It mainly gets the nearest. If attached: ]] function Tactic:TryAttachSquad( melee, match_stance, radius, min_strength, health, best_attach_unit ) --print("Tactic:TryAttachSquad | us: "..self.stats:GetSquadName()) -- Finaldeath rewrite -- Will: -- Attach if broken -- Attach at full health -- Match up units specifically --[[ self.stats:GetSquadName() == "ork_squad_mek_boy" ]] -- Who we attach to local attach_to = nil -- FD: Always attach to certain squads we love even if broken or not low HP if best_attach_unit ~= nil then -- Best attach unit is a table for i = 1, table.getn(best_attach_unit) do -- Filters squads for the exact best squad local special_filter = function( squad_ai ) return (squad_ai:GetSquadName() == best_attach_unit[i]) and self.squad_ai:CanAttachTo( squad_ai ) and not squad_ai:IsCapturing() and not cpu_manager:InSubState( squad_ai:GetID() ) end -- Find something attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), radius * 2, special_filter ) -- If we have something found... if attach_to ~= nil then print("Tactic:TryAttachSquad | us: "..self.stats:GetSquadName().."| Attaching to SPECIAL: "..attach_to:GetStats():GetSquadName()) -- ...attach self:DoMoveAttach( attach_to, true, best_attach_unit ) -- We will possibly force stance change if match_stance then if(melee) then attach_to:DoSetMeleeStance( SquadAI.MSTANCE_Assault ) else attach_to:DoSetMeleeStance( SquadAI.MSTANCE_Ranged ) end end -- Stop now return attach_to end end end -- If broken if self.squad_ai:IsBroken() then -- If broken, try and attach to any nearby unbreakable squads (ie: IsAffectedByMorale()) -- NB: Need to make sure we can check who is immune to morale proper - engineers -- get IsAffectedByMorale() set to FALSE if and only if they are building or something. -- and no where else I can tell this is functions return value is changed. -- FD: Use IsBroken for now -- Filters squads for the exact best squad local unbreakable_filter = function( squad_ai ) return not squad_ai.IsBroken and -- not squad_ai.infantrytactic:IsAffectedByMorale() and self.squad_ai:CanAttachTo( squad_ai ) and not squad_ai:IsCapturing() and not cpu_manager:InSubState( squad_ai:GetID() ) end -- Find something attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), 20, unbreakable_filter ) -- If we have something found... if attach_to ~= nil then print("Tactic:TryAttachSquad | us: "..self.stats:GetSquadName().."| Attaching to UNBROKEN: "..attach_to:GetStats():GetSquadName()) -- ...attach self:DoMoveAttach( attach_to ) -- We will possibly force stance change if match_stance then if(melee) then attach_to:DoSetMeleeStance( SquadAI.MSTANCE_Assault ) else attach_to:DoSetMeleeStance( SquadAI.MSTANCE_Ranged ) end end -- Stop now return attach_to end end -- We will attach if: -- - We are not broken -- - We have less then "health" percent health if ( (not self.squad_ai:IsBroken() and (health == nil or self.squad_ai:GetHealthPercentage() < health)) or -- Special case: Attach early to correct squad if we are in tier 3 or 4 and are in combat ((self.squad_ai:IsInCombat() and cpu_manager:GetTierLevel() == 3) or cpu_manager:GetTierLevel() == 4) ) then -- Minimum strength of squad we want to attach to -- - Always have a minimum if none is supplied, although a 0 input is valid. if min_strength == nil then min_strength = 160 + (cpu_manager:GetTierLevel() - 1) * 40 end -- Filters squads for ranged units only local range_filter = function( squad_ai ) return squad_ai:GetProRatedCost() >= min_strength and self.squad_ai:CanAttachTo( squad_ai ) and squad_ai:IsRanged() and not squad_ai:IsBroken() and not squad_ai:IsCapturing() and not cpu_manager:InSubState( squad_ai:GetID() ) end -- Filters squads for melee units only local melee_filter = function( squad_ai ) return squad_ai:GetProRatedCost() >= min_strength and self.squad_ai:CanAttachTo( squad_ai ) and not squad_ai:IsRanged() and not squad_ai:IsBroken() and not squad_ai:IsCapturing() and not cpu_manager:InSubState( squad_ai:GetID() ) end -- Attach to ranged units if not melee then -- Find ranged squad local attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), radius, range_filter ) -- Try for melee unit if we don't care about the stance if attach_to == nil and not match_stance then -- Find melee squad attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), radius, melee_filter ) end -- If we have something found... if attach_to ~= nil then print("Tactic:TryAttachSquad | us: "..self.stats:GetSquadName().."| Attaching to RANGED: "..attach_to:GetStats():GetSquadName()) -- ...attach self:DoMoveAttach( attach_to ) -- We might have attached to a melee unit. Force this unit to be a ranged stance. if match_stance then attach_to:DoSetMeleeStance( SquadAI.MSTANCE_Ranged ) end -- Stop now return attach_to end -- Attach to melee units else -- Find melee squad local attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), radius, melee_filter ) -- Try for ranged unit if we don't care about the stance if attach_to == nil and not match_stance then -- Find ranged squad attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), radius, range_filter ) end -- If we have something found... if attach_to ~= nil then print("Tactic:TryAttachSquad | us: "..self.stats:GetSquadName().."| Attaching to MELEE: "..attach_to:GetStats():GetSquadName()) -- ...attach self:DoMoveAttach( attach_to ) -- We might have attached to a ranged unit. Force this unit to be a melee stance. if match_stance then attach_to:DoSetMeleeStance( SquadAI.MSTANCE_Assault ) end -- Stop now return attach_to end end end -- Return either nil, or the squad we attached to. return attach_to end --[[ This obviously is useful if we are in melee and really should be attached... Need to revamp a bit: - Attach to things depending on if we are really close and might as well (IE: they are not bad at melee) - Do more things then just attach at 30% health. At 70% we might want to attach to a very nearby squad. - Since this assumes all heroes are melee heroes (sets the squad's melee stance to assault), it will actually do worse for some heroes who could play well at range. Must alter that. - Attach ranged based heroes to ranged squads nearby even if they are not strong enough if in combat/being attacked. - Some checks if we are defending or attacking, or even doing neither, might be a good idea. ]] -- Attach to something in combat. function Tactic:TryAttachSquadMelee() --if I'm in combat if not self.squad_ai:IsBroken() and self.squad_ai:IsInCombat() then -- If we have health % < 30% we are dying if self.squad_ai:GetHealthPercentage() < 0.3 then -- Attach to melee *or ranged* units nearby based on if they are not busy or broken. Attach to anything! local attachable_filter = function( squad_ai ) return self.squad_ai:CanAttachTo( squad_ai ) and not squad_ai:IsBroken() and not squad_ai:IsCapturing() and not cpu_manager:InSubState( squad_ai:GetID() ) end -- Find close by squads. 10M range. local attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), 10, attachable_filter ) else -- Else, Health > 30% -- Attach to melee units nearby based on if they are not busy or broken local melee_filter = function( squad_ai ) return self.squad_ai:CanAttachTo( squad_ai ) and not squad_ai:IsRanged() and not squad_ai:IsBroken() and not squad_ai:IsCapturing() and not cpu_manager:InSubState( squad_ai:GetID() ) end -- Find close by squads. 10M range. local attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), 10, melee_filter ) end -- If we find a squad... if attach_to ~= nil then print("Tactic:TryAttachSquadMelee | us: "..self.stats:GetSquadName().." | Attaching to: "..attach_to:GetStats():GetSquadName()) -- ...attach... self:DoMoveAttach( attach_to ) -- and set the stance of the squad to Assault. attach_to:DoSetMeleeStance( SquadAI.MSTANCE_Assault ) end end -- No return? end -- This will always attach our Will to most any squad available to stay alive...after all, "Fire at will";-) function Tactic:TryAttachAssassinate() -- Filter -- Almost any squad (ranged, or melee), that isn't broken or capturing, and is 200 or higher rating. local attachable_filter = function( squad_ai ) return squad_ai:GetProRatedCost() >= 200 and self.squad_ai:CanAttachTo( squad_ai ) and not squad_ai:IsBroken() and not squad_ai:IsCapturing() end -- Find a squad in a 60M range. local attach_to = cpu_manager:GetClosestSquad( self.squad_ai:GetPosition(), 60, attachable_filter ) -- Attach to one if we find any if attach_to ~= nil then -- Attach self:DoMoveAttach( attach_to ) -- Do not melee attack with this squad attach_to:DoSetMeleeStance( SquadAI.MSTANCE_Ranged ) end end -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- -- FD: Altered -- This will set attachment information -- Pass in keepattached to be TRUE if the attaching commander should stay, if they match the commander name that is function Tactic:DoMoveAttach( attach_to, keepattached, best_attach_units ) -- Search table InfantryTactic.KeepAttached -- Match such as GetID() of the squad, and the unit to keep attached local attach_to_id = attach_to:GetStats():GetID() -- Default keepattached to false if keepattached == nil then keepattached = 0 else keepattached = 1 end -- print the table print("Tatic:DoMoveAttach: Attempting to add ID:"..attach_to_id..": to table, with name:"..self.stats:GetSquadName()) -- This is our commander attachemnt information hash. -- - Why hash: Using the ID would mean we have a million empty entries up to "ID", loverly! InfantryTactic.AttachedInfo[attach_to_id] = { } -- Add to the squad's ID, the commander name, and if we want to keep him on forever. InfantryTactic.AttachedInfo[attach_to_id]["commander"] = self.stats:GetSquadName() InfantryTactic.AttachedInfo[attach_to_id]["keep_attached"] = keepattached --print("|| ADDED:"..InfantryTactic.AttachedInfo[attach_to_id]["keep_attached"].."|| should equal :"..keepattached.."||") -- Add in our stance and ranged information too InfantryTactic.AttachedInfo[attach_to_id]["is_ranged"] = self.squad_ai:IsRanged() InfantryTactic.AttachedInfo[attach_to_id]["stance_melee"] = self.squad_ai:GetMeleeStance() InfantryTactic.AttachedInfo[attach_to_id]["stance"] = self.squad_ai:GetStance() -- Add in the info from what the commander likes to attach to if valid if best_attach_units ~= nil then InfantryTactic.AttachedInfo[attach_to_id]["best_attach_units"] = best_attach_units end -- Keep units attached for a minimum amount of time to stop them detaching too fast -- - 120 seconds (2 minutes) InfantryTactic.AttachedInfo[attach_to_id]["time_limit"] = cpu_manager.cpu_player:GetGameTime() + (8 * 120) -- print all! --table.foreach(InfantryTactic.KeepAttached, print) -- print the table print("Attaching the commander: "..self.stats:GetSquadName()..": to: "..attach_to:GetStats():GetSquadName()) -- Do also attach :-D self.squad_ai:DoAttachSquad( attach_to ) end -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------
Example of changed tatics file, for mekboy:
---------------------------------------- -- File: 'mekboytactic.ai' -- Edited by Thudmeizer @ 09.03.2005 -- Edited by LarkinVB @ 16.08.2005 class 'MekBoyTactic' (OrkInfantryTactic) MekBoy = {} function MekBoyTactic:__init( squad_ai ) super( squad_ai ) end function MekBoyTactic:UpdateAbilities() if MekBoy.zap_id == nil then MekBoy.zap_id = cpu_manager.stats:GetAbilityID( "ork_tank_zappa" ) end if MekBoy.superstick_id == nil then MekBoy.superstick_id = cpu_manager.stats:GetAbilityID( "ork_superstick_bomb" ) end end function MekBoyTactic:IsAttacker() --assassinate win condition -- never attack return not cpu_manager.assassinate end function MekBoyTactic:GetName() return "Mek Boy Tactic" end function MekBoyTactic:DoAbilities() MekBoyTactic.UpdateAbilities(self) Ability.DoAbilityTarget( self.squad_ai, MekBoy.zap_id, Ability.Filters.CloseVehicleEnemy ) Ability.DoAbilityTarget( self.squad_ai, MekBoy.superstick_id, Ability.Filters.CloseVehicleEnemy ) end function MekBoyTactic:Update() if self:IsComplete() then return end --assassinate win condition -- always attach to a squad if cpu_manager.assassinate then self:TryAttachAssassinate() else --state machine if not InfantryTactic.Update( self ) then return end best_attach_units = { "ork_squad_nob", "ork_squad_slugga" } if self:TryAttachSquad( false, true, 50, nil, 0.3 ) == nil then self:TryAttachSquadMelee() end end end
Have still not added IsInStateAttackMode() and commanders sometimes attach to some things they would be better off not attaching too.
NB: this is beta 12 code, but beta 13 shouldn't be any different. Note the extra print statements might slow AI operation a bit and its not optimised yet at all. Just showing some progress.
Edited by Finaldeath, 12 March 2006 - 01:55 PM.
#8
Posted 16 March 2006 - 01:26 AM
- If a commander is attached to a squad they will stay on, to always set aside some resources, if no desperate research is taking place, to fill the squad to full strength - or at least half strength.
- Possibly only when attacking/defending.
I have seen (with b13) a ork army with a total pop of 9, which later went to 13 as this happened, having their one, new, killa kan, upgrading to a missile launcher.
Of course, there was no commander, but more boyz were needed at that point as opposed to upgrades, heh.
Maybe this is more hinging on the general AI.
anyway, it equally applies to other armies. If a Chaos Lord attached to some beserkers, the bonuses induced would be better if the squad is larger/constantly reinforcing. Farseer gains a massive bonus from seer councils etc.
Basically, I wondered if a way of having a "save resources for certain reinforments/upgrades" could be initiated and used anywhere.
#9
Posted 16 March 2006 - 01:56 AM
But, one of the most popular suggestions for fixing the 1.41 Orks is to double the potential size of the Tank Busta Squad. The Orks need something to take out all those Space Marine tanks, IG Tanks, and Eldar Fire Prisms, since the Ork Tanks don't have what it takes. But, the Ork Tank Busta Squads are always killed long before they kill any tanks.
Of course, some have suggested that purposefully attaching a Big Mek or an Ork WarBoss to a squad of Tank Bustas might be a way for the Tank Busta Squad to last just barely long enough to take down a tank.
Making the Ork Waagh Banners tougher with more hit points and making them do more damage so that they are as good as any turret is another suggestion. In that Soul Forge game I played with B13, I lost a couple of Waagh Banners and suddenly I could no longer make tanks. I mean, nobody else loses their ability to make tanks if you destroy their turrets.
Anyway, ever since 1.41, whenever I want a hard game, I put Orks on my side, and whenever I want an easy game at the HARD setting, I put Orks on the enemy's side. And, that doesn't even count when I play as the Orks. I just have a devil of a time lasting long enough to get a win playing as the Orks, with something like B13 or B12. So, anything you can do to make the Ork AI play more perfectly or more efficiently over the long haul would indeed be a step in the right direction.
The Orks do really well on average with B13 on the smaller maps where they can get into close combat melee quickly and do their damage. It's on the bigger or more intricate maps that the 1.41 Plain Vanilla stuff comes shining through and the Orks fall down. I mean in PV 1.41, the Orks have nothing at all that can stand up to Tier 4 Space Marines and actually hold their own let alone win.
Anyway, I hope Arkhan and Thud have time to look at FinalDeath's input here and elsewhere, because I think he is right on track when it comes to his comments about the Orks and the Chaos, and maybe if something could be squeezed into the Final Release to give them a bit more End Game final tier teeth, that might not be a bad thing. I am seeing some of this show up in the larger map longer games that I just started testing with B13.
Edited by ThetaOrion, 16 March 2006 - 02:03 AM.
#12
Posted 18 March 2006 - 05:33 PM
Its a bit useless sometimes a commander attaching to a nice, newly built squad, and then it just getting blown away since it has no upgrades (eg: power claws) or seargents (eg: aspiring champions on cultists) or even a complete squad (eg: few sluggas).
Main reason is for the units that have teleport (mekboy, sorceror, other new races), that have a bonus for multiple amounts (seer council), or have a good weapon or are powerful anyway (nobz, assault terminators ).
Glad its possible, if it isn't implimented I'll look into it but it'd require more knowledge then I have currently to do anything about it.
#14
Posted 18 March 2006 - 09:50 PM
I'll likely add into the code some checks to make sure units with upgrades (which are ranged squads) do not get attached to unless at the "Low health and don't want to die" stage.
For melee units though, nobz/sluggas/etc., upgrades for a warboss/mekboy squad (latter especially) helps
Any suggestions welcome. Some of my current choices might not be too appropriate in games that I don't play often or races I rarely play as for instance.
#16
Posted 19 March 2006 - 12:21 PM
Of course, I havn't written the code for it so I'm not sure al the parts are there yet.
#17
Posted 19 March 2006 - 02:48 PM
#20
Posted 19 March 2006 - 07:56 PM
...And, Arkhan, reinforcing a squad with a commander attached which "should be" reinforced (IE: this is the best squad possible we can attach to, so beef it up!), like Nob squads, terminators, seer councils and possessed marines, would take priority over just "the best" outright, I should think
I need to know how to get upgrades so commanders don't attach to ranged units with special weaponry, which means usually they are too far out of range to fire thier own gun.
Edited by Finaldeath, 19 March 2006 - 07:57 PM.
Reply to this topic
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users