Staredit Network > Forums > SC2 Assistance > Topic: AI - looking for simple Mass Attack solution
AI - looking for simple Mass Attack solution
Apr 20 2014, 8:20 pm
By: harsap  

Apr 20 2014, 8:20 pm harsap Post #1



Hi,

I'm fairly new and looking for a simple, performance friendly Mass Attack Solution (which I'm unable to find).

Case:
1 Cpu, periodically spawning loads of Units, up to a few hundred on field a time. No buildings or anything.
6 Players, most of the time controlling 1 Hero Unity. By times might have some extra Units or defensive buildings.

Task:
CPU spawns approximately 12-20 Units every 15 seconds, after each spawn every Unit on the Map shall attack a random Player/Unit.

Basically I'm looking for a similar function like SCBW's Random Suicide Mission.
The only thing similar I found is Global Suicide but it only forces attacks on buildings, which makes it completely useless for my needs and anyway, the "closest target" goal won't fit well either.



None.

Apr 20 2014, 8:44 pm Devourer Post #2

Hello

Did I get this correctly? :: one computer-player spawns units and the six players have one hero to control each -most of the time. The units owned by the computer are to attack random targets on the map, even their friends - as in the computer allows friendly fire.

Should every unit attack the same unit or should every unit attack a random unit (read: do they have the same or different targets at a time)?
Should they really get a random target on the map and walk to it first before attacking it or do you want the units to prefer nearby targets?



Please report errors in the Staredit.Network forum.

Apr 20 2014, 9:07 pm harsap Post #3



The Computer is supposed to attack the Players, not his own Units.

The AI should command each of his Units to chase a random Player Unit, so if theres 8 Player Units and 400 CPU Units approximately 50 would go for each of the Player Units. However, it would be great if the cpu units within close range (50-100 pixels or so) to a Player Unit would actually go for this one when receiving the command - once it has chosen its goal it should just straight go for this one until the next AI command is run. When the targeted Unit "disappears" it's ok if the chasing Units stop until receiving the next command, though they should still fight back if attacked.
This was basically the result in SCBW with the Suicide Mission and worked quite well even with 1500 CPU Units.

Hope I was able to describe it better this time.



None.

Apr 20 2014, 9:46 pm Devourer Post #4

Hello

Alright, I think I got it.
Please take note that I am writing this freely, since I can not access the editor right now. Some actions etc might be labeled incorretly here, but I am pretty confident, that they all exist.

First off, to make triggers easier, we will need a variable of type Player Group [PLAYERGROUP] in which every Player that can/should be attacked by the computer is part of it, as long as that Player is in the game. I can not write this for you since I do not know required details of the map.
We also need a variable-array of type Unit [PLAYERUNIT[X]] which contains the "hero"-units of the players 1-8. You would be best setting this up at the start of the map.

For this example, Player 10 is the one computer, Players 1 to 8 are the human players being attacked.
I further assume, that you have already created a trigger that spawns these units.
Add an action called "Run Trigger" in that one and select the new trigger I describe below:

Events and Conditions are left empty.
Local Variables:
Integer :: Players = 0 // Will hold the number of active players in the game
Integer :: UnitsPerPlayer = 0 // How many units will attack each player (50, in your example, given there were 400 units
Integer :: NumberOfUnits = 0 // Number of units by the computer
Integer Array :: UnitsAttackingPlayer[8] = 0 // This array will hold the number of units already attacking the player X, where X is the index.
Double :: forceRange = 4.0 // The range in which units are marked as nearby and thus are forced to attack that nearby player unit
Unitgroup :: alreadyAttacking = Empty Unitgroup // The unitgroup in which we throw all units that already received a command

Actions:
// We set the variables
Set Variable : Set 'Players' to (Number of Players in Playergroup ( active players))
Set Variable : Set 'NumberOfUnits' to (Number of Units in Unitgroup ( Units in Region matching conditions ( Any Units by Player 10 (...))))
Set Variable : Set 'UnitsPerPlayer' to (Arithmetic (Integer) ( NumberOfUnits / Players ))

// We now force enemies to attack nearby players
foreach Player in Playergroup (PLAYERGROUP)
{
Pick each unit in unitgroup ( units in region matching conditions ( Any Units by player 10 in (circle to region ( Point ( Position of unit PLAYERUNIT[pickedPlayer]) radius forceRange)))
{
Issue command (targeting Unit) : picked Unit Attack PLAYERUNIT[picked Player];
Add Unit to Unitgroup : picked Unit to alreadyAttacking;
Modify Variable (Integer) : Modify UnitsAttackingPlayer[picked Player] +1;
}
}


// Now we probably have units left not having a new attack
Pick each units in Unitgroup ( Any Unit by Player 10 in Entire Map)
{
// We add an If to see if the unit is having a target already
if(unit is in unitgroup (picked unit in alreadyAttacking == false))
{
foreach Player in Playergroup (PLAYERGROUP)
{
if(unitsAttackingPlayer[picked Player] < UnitsPerPlayer)
{
Issue command (targeting Unit) : picked Unit Attack PLAYERUNIT[picked Player];
Add Unit to Unitgroup : picked Unit to alreadyAttacking;
Modify Variable (Integer) : Modify UnitsAttackPlayer[picked Player] +1;
}
}
}
}


Now this is a draft, but it should work.
Summing up:
- Let all "nearby" units attack them and add those units into a group
- Check if the unit is in that group and if not, let it attack a player.

Note:
This system assumes that Pick each Unit in Unitgroup picks "random" units, which it does if I remember correclty.



Please report errors in the Staredit.Network forum.

Apr 20 2014, 10:38 pm harsap Post #5



Wow thank you, thats really an extensive answer. It will probably take me some time to go through all this and try to understand just the half of it. Whatever, it's quite late here already so I might not be able to report about my success till tomorrow.

First of all Ill need to patch my SC2 version for ENG language, else I'm going nowhere.

Post has been edited 1 time(s), last time on Apr 20 2014, 11:15 pm by harsap.



None.

Apr 21 2014, 10:50 am harsap Post #6



Surprisingly I managed to more or less recreate your draft. However theres always just a few of the recent spawned ones forced to attack and they just attack one of the Units I spawn for the player since I found no other way to assign a Unit to a Unit variable other than "last created unit".

Ah well, actually the reason that not all CPU Units get an Order might be related to the part where you wrote to not use any Event or Condition. Since the triggers just didnt do anything without an Event or Condition, I put them under the same Event as where the CPU Units get spawned - and since this happens only 1 time every 5 seconds I suppose just not all Units are catched...

Post has been edited 1 time(s), last time on Apr 21 2014, 10:56 am by harsap.



None.

Apr 21 2014, 4:38 pm payne Post #7

:payne:

Quote from harsap
since I found no other way to assign a Unit to a Unit variable other than "last created unit"
"Pick Each Unit in Unit Group": set the Unit Group to "Unit from Unit Group Matching Conditions". Then change the variables so that they fit properly the CPU's units (Any Unit, Player 15, Entire Map... I have no idea). Leave the "At Most".
Then, create a Global Variable which is of type "Unit Group", and in the loop I made you create, you must add an "Add Unit To Unit Group" action and set the unit to "Picked Unit" and the Unit Group to that Global Variable.
With this, you have a Unit Group variable which contains all your CPU units. To be able to select all of them individually to order them to do stuff, you can then do "Pick Each Integer" from "1" to "Number of Units in Unit Group" (set that Unit Group to the global variable), and do "Issue Order" for the "Unit From Unit Group" setting the ID of that unit to being "Picked Integer".

You'd probably have to "Remove Unit From Unit Group" every time they would die, and when updating that variable to contain newly create units, you'd have to make sure that the unit isn't already in the unit group.



None.

Apr 21 2014, 6:26 pm harsap Post #8



Ugh, I don't see how all the stuff about the CPU Unit Group is related to the Player Unit Variable.

It rather looks like you are completing the draft of Devourer, and I'm concerned there is still lots left for it to work proper. Elsewhere I read that Removing Units from Groups has bad performance impact.

Honestly, none of the above looks simple, or performance friendly... Till now I spent about 20 Hours just to discover things like hidden Stuff within clickable brackets, going through endless references in the Data Editor or following outdated and now useless tutorials (no current Solution could be found).

I doubt I will have much joy with the SC2 Editor...



None.

Apr 21 2014, 9:01 pm payne Post #9

:payne:

Once you get how it works, it's actually quite fun to play with it. But it did take me a long while to understand the Data Editor properly, and the Trigger module also has a few hidden secrets.



None.

Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[08:46 pm]
RIVE -- :wob:
[09:13 am]
NudeRaider -- :wob:
[2024-6-21. : 3:59 am]
Ultraviolet -- :wob:
[2024-6-19. : 6:26 pm]
Ultraviolet -- :wob:
[2024-6-18. : 8:38 am]
Zycorax -- :wob:
[2024-6-18. : 3:14 am]
O)FaRTy1billion[MM] -- :wob:
[2024-6-15. : 11:09 pm]
Ultraviolet -- :wob:
[2024-6-12. : 6:23 am]
Ultraviolet -- got some light recalls behind too
[2024-6-12. : 12:07 am]
O)FaRTy1billion[MM] -- 🦗
[2024-6-11. : 9:53 pm]
Wing Zero -- I wonder how he knew I was in the market for a good cricket bat
Please log in to shout.


Members Online: Ultraviolet, Roy