Creating units

From WiCWiki

Jump to: navigation, search

Contents

  • When you finished this lesson you will be able to create friendly, neutral and enemy units.

Units are, of course, a big part of the game. The whole game play can change depending on what kind of units you add to the map both friendly and enemies.


Set the teams on a map

The first important thing to consider is which team we can use on the map. This is set in the wic\map\mapName.juice file in the myWicedMap -> myMissionStats.

myAllowedTeam1 USSR
myAllowedTeam2 NATO
myAllowedTeam1SinglePlayer NATO
myAllowedTeam2SinglePlayer USSR

On a single player map, we only change ‘myAllowedTeam1SinglePlayer’ and ‘myAllowedTeam2SinglePlayer’. ‘myAllowedTeam1SinglePlayer’ is always the team the player should belong to. On this map, the player belongs to the NATO team.

We can choose between US, NATO and USSR. If you create a map in ‘WICEd’ the default value on the Single player allowed teams are neutral. You must change this to the team you want to use, else all reactions that triggers on the team will be screwed up.


In single player we use the ‘myAllowedTeam1’ and ‘myAllowedTeam2’ when we have AI players on the map. If you don’t plan to use the AI, use the default value.


More about this in the chapter about AI.

Create enemy units at the village

Let us add our first Russian unit, an APC, to the map.


We add a new function in the allunits file, Village, where we will create all the Russian units that belongs to the Village event.


Just as we did when we created the player starting units, we’ll use the CreateGroup function for all the Russian units. For more information about this, see the chapter about starting units.


Create a ‘grpVillageRu1’ variable in the mapvars.py file. We’ll use this variable to save the group in. We’ll also use the variable name as name of the group.

def Village():
    mapvars.grpVillageRu1 = CreateGroup( 'grpVillageRu1', [ USSR_BMP_3 ], 'areaVillageSpawn1', PLAYER_SCRIPT, TEAM_USSR )

You can create units with drops ships as well but we will cover that in a sub chapter not far away.

Create units at position

Sometimes there’s a good reason to first create an empty group and then fill it with units. For example, if you want to set up a reaction that will trigger on a group but you don’t want the units in the group to be created at the moment.

First create an empty group like this.

grpMygroup = CreateGroup( ' grpMygroup ', [], , PLAYER_SCRIPT, TEAM_USSR )

- The first parameter is the name of the group and you still need to have that.

- The second parameter is the empty list of no units. This must be a list.

- The third parameter can be an area, an empty string or None.

- The fourth parameter is which player the units shall belong to.

- The fifth parameter is which team the units shall belong to.


When you want the units to be created, preferable in another method, you do like this.

grpMyGroup.CreateUnitsAtPosition( [USSR_BMP_3], 'areaKillArtyRuSpawn' )

- The first parameter is the unit or units you want to add to the group.

- The second parameter is a spawn position. You will need this whether or not you have a position in the ‘CreateGroup’ function.


There are more parameters you can play around with if you like, we seldom or never do that. You can find the method in the wic\python\group\group.py file.


Use drop ships to create units

The big advantage when using drop ships are that the units won’t just appear in the player’s line of sight rather get dropt in, as when the player order down units. This makes is very, very useful especially if there’s a limited amount of good spawn positions or if there’s a chance the player have line of sight to where you want to spawn the units. If you use the drop ships when you create units remember that, as with player units, it takes about 20 seconds for the units to arrive.


To make the enemies drop ships visible you must use the ShowAllDropships( True ) function with true as only parameter. You can use this line of code everywhere you want, preferable in the server.py file and we ususally use it in the OnGameStarted function like this. Just make sure you call the function you write it in before you call any function that will create the units.


def OnGameStarted():
    if IsSinglePlayer():
        DebugMessage( "OnGameStarted:: Singel" )         

        [More code goes here]                           

        # Show Enemy Teams Dropships
        ShowAllDropships( True )
                   

On every group you want to be dropped in by planes you must use the ‘SetUseAirDrop’ method with the only parameter set to true. You can use this method in combination with the rest of the group code in the allunits.py. Here’s an example when it is necessary to first create an empty group because you can’t use the ‘SetUseAirDrop’ method before the group is created and you must use it before you actually create the units if you want them to be dropped.


def SetupUnits():
    grpMygroup = CreateGroup( ' grpMygroup ', [], , PLAYER_SCRIPT, TEAM_USSR )
    mapvars.grpMyGroup.SetUseAirDrop( True )

def MyUnits():
    grpMyGroup.CreateUnitsAtPosition( [USSR_BMP_3], 'areaKillArtyRuSpawn' )

Drop units at position

The ‘DropUnitsAtPosition’ method works almost the same as the ‘CreateUnitsAtPosition’ method, which we covered a couple of sub chapters before. If you just want a couple of units to be dropped, this is what you are looking for. If you want a group to be refilled with drop ships, it is covered in a couple of sub chapters.


Make sure you have created a group and when you want the units to be dropped, you do like this.


grpMyGroup.DropUnitsAtPosition( [USSR_BMP_3], 'areaKillArtyRuSpawn' )


- The first parameter is the unit or units you want to add to the group.

- The second parameter is a drop position. You will need this whether or not you have a position in the ‘CreateGroup’ function.


The ‘DropUnitsAtPosition’ method calls the ‘CreateUnitsAtPosition’ method but with the last parameter set to True. You can find the method in the wic\python\group\group.py file.


Move the group

Now we have an enemy group that stands completely still on the position we created it and that’s not that fun so we want to move it.

To move units in a group there is several methods, MoveUnit, MoveUnitCover, MoveGroup and MoveMultipleTargets. The easiest way is to use MoveGroup that moves the group to the position that we send in.


aGroup.MoveGroup( aTarget, aDirection = None, aHeading = None, aTeleport = False, aBackwards = False )


-The first parameter is the position where we want the group moved to.

-The second parameter is in what direction the group formation shall look at. The default value is ‘None’.

-The third is the heading of each individual unit in the group. The default value is ‘None’.

-The fourth parameter is if the group shall be teleported to the target position. The default value is ‘False’ so the units have to travel to their destination.

-The fifth and last parameter is if the group shall move backwards. The default value is false so it moves forward.


When we want to move the grpVillage1 group from its spawn position, ‘areaVillageSpawn1’, to the ‘CP_Village’ command point with the group method ‘MoveGroup’ we do like this.


mapvars.grpVillageRu1.MoveGroup( ‘CP_Village’ )


Here is the code we got so far.

##---------------------------------------------------------------

#---------------------------  Village ---------------------------       
def Village( ):
    DebugMessage( 'allunits.Village::' )

    # Create a USSR group that are own by the script player.
    mapvars.grpVillageRu1 = CreateGroup( 'grpVillageRu1', [ USSR_BMP_3 ], 'areaVillageSpawn1', PLAYER_SCRIPT, TEAM_USSR )
    mapvars.grpVillageRu1.MoveGroup( 'CP_Village' )


Before we can start the game we must call the allunits.py ‘Village’ function from the server.py file, else you won’t se any units. We add it in the beginning of the VillageCam function like this.

def VillageCam( ):
    DebugMessage( "VillageCam::" )

    # Create the units that are defending the village.
    allunits.Village( )


If you don’t have a camera function, call it from where ever you see fit.


If you start the game now the Russian unit will move to the command point and stand in it which means that you must kill the unit before you can take the command point.

Add behaviors to a group

If you’ve started the game and tried to attack the group so far you might have noticed that the unit don’t react. We add behavior scripts to create a more interesting dynamic to the battlefield and to make the units react when it’s engaged in combat we use group behaviors. We have two different types of behaviors; ‘AttackBehavior’ and ‘BaseBehavior’. The attack behavior affect how the groups react when attacked and base behavior is what the groups should do when it don’t have any other orders.


The Base behavior

Base behaviors are what the group groups should do when it don’t have any other orders. If it gets an order it will interrupt the base behavior, do the new order, and then return to the base behavior. The default base behavior is BHB_Idle which means that the group won’t do anything.


To give a group a base behavior we use the SetBaseBehavior method and send in the behavior we want the group to have.


aGroup.SetBaseBehavior( aBehavior ) 


To bring some life to the ‘APC’ we will remove the ‘MoveGroup’ method and add the base behavior ‘BHB_IdleUnits’ instead. ‘BHB_IdleUnits’ behavior gives the group a new move order at regular intervals to random positions around the position we use in the ‘IdleUnits’ function.


mapvars.grpVillageRu1.SetBaseBehavior( BHB_IdleUnits( 'areaVillageRuMove1' ) )

For the complete list with Base Behaviors check the behavoir file in wic\python\group\ behavior.py.

All base behaviors start with ’BHB_’.


Attack behavior

If you add one ‘attack behavior’ to a group that behavior will override any base behavior or order the group have when it is engaged in combat. The default attack behavior that a group has is BHA_Fearless and it means that it does not do anything when the group gets engaged in combat just continue execute the current orders it has.


To give a group an attack behavior we use the SetAttackBehavior method and send in the behavior we want the group to have when it is engaged in combat.


aGroup.SetAttackBehavior( aBehavior )


-The parameter is the attack behavior that the group shall have.


In this test map, we will use several attack behaviors, on the grpVillageRu1 group we will use BHA_StandFast, which makes the group stop and it turns toward the attacker.


mapvars.grpVillageRu1.SetAttackBehavior( BHA_StandFast( ) )


For the complete list with Attack Behaviors check the behavoir file in wic\python\group\ behavior.py.

All attack behaviors start with ’BHA_’.


When we have removed the MoveGroup and added the behaviors to the Village function in allunits it should look like this.


##---------------------------------------------------------------
#---------------------------  Village ---------------------------       
def Village( ):
    DebugMessage( 'allunits.Village::' )

    # Create a USSR group that are own by the script player and add an attack and base behavior.
    mapvars.grpVillageRu1 = CreateGroup( 'grpVillageRu1', [ USSR_BMP_3 ], 'areaVillageSpawn1', PLAYER_SCRIPT, TEAM_USSR )
    mapvars.grpVillageRu1.SetBaseBehavior( BHB_IdleUnits( 'areaVillageRuMove1' ) )
    mapvars.grpVillageRu1.SetAttackBehavior( BHA_StandFast( ) )


Now we can start the game again and watch the group behave different than before, with the attack behavior. It might be a good idea to use the ‘hold fire’ command on your units so they don’t kill the ‘APC’ immediately.

Set formations on groups

When we create a group, it will have ‘line formation’ by default and that means that all units will try to arrange themselves in a perfect line. Line formation works for vehicles but with infantry’s it just looks strange. So, we want to change the formation and there are three different that we can use.

FORMATION_LINE – All units arrange in a line.

FORMATION_BOX – All units arrange in a box.

FORMATION_COVER – The units will try to find position where they are in cover.


When we want to change the formation that a group have we use the SetFormation method.


SetFormation( aFormation, aDistance = DEFAULT_FORMATION_DISTANCE )

-The first parameter is what type of formation the group shall use.

-The second is how far apart the units shall stand. The default distance is eight units.


To make the line or the box that the units are standing in a little irregular we can set an offset value with the SetFormationOffset function and if we feel that the unitsare standing to close together, we can use the SetFormationWidthOffset method.


SetFormationOffset( anOffset )


-The parameter is a max distance to offset each unit from the perfect line or box.


SetFormationWidthOffset(anOffset )


-The parameter is how far apart the units in the group shall stand.


Set box formation on an infantry squad

Now let us create a group with an infantry squad with five units. We create it the same way as with the previous groups.


mapvars.grpVillageRu2 = CreateGroup( 'grpVillageRu2', [ USSR_MARINE, USSR_MARINE, USSR_AA_INFANTRY, USSR_MACHINE_GUNNER, USSR_ANTITANK ], 'areaVillageSpawn3', PLAYER_SCRIPT, TEAM_USSR  )


We use the attack behavior to BHA_Defensive which means that the group will keep a distance to the attacker when they are engaged in combat.


mapvars.grpVillageRu2.SetAttackBehavior( BHA_Defensive(  ) )

The base behavior we set to BHB_IdleInfantryCover, it works as the BHB_IdleUnits but try to move the units to positions where they have cover.

mapvars.grpVillageRu2.SetBaseBehavior( BHB_IdleInfantryCover( 'areaVillageRuMove1' ) )

We want the grpVillageRu2 to try keeping its units in cover so we set the formation to FORMATION_COVER.


mapvars.grpVillageRu2.SetFormation( FORMATION_COVER )


Transport infantry units

Infantry units are pretty slow so it can be nice to transport them in vehicles. It looks pretty cool as well.


You can’t transport more than one squad in each transport vehicle.


To get the infantry squad in to a transport vehicle we use the EnterGroup method on the group with infantry units. It is easier if the vehicles and infantry’s are in the same group but they do not have to be.


aGroup.EnterGroup(aGroupToEnter = None, aInstantFlag = False )


-The first parameter is the group with transport units that the infantry squad shall try to enter. The default value is ‘None’ and means that the squads shall enter any possible transport units in the same group.

-The second parameter is if the squad shall enter the transport vehicle instantly or if they have to get close enough to enter. The default value is False which means that they don’t enter the transport instantly.


It can be a good idea to tell units to enter instantly, for example if you use amphibious vehicles and they start in the water.


When we want the infantry to exit the transport vehicle, we use the ‘UnloadAll’ method on the group. If they are in different groups, we use ‘UnloadAll’ on the group with the transport units.


aGroup.UnloadAll()


If the infantry and transport vehicle are in the same group, we have to make it a ‘transporter group’. That means that infantry units in a transport vehicle will not get any move orders as they would exit the transport if they got a one.


aGroup.SetTransporterGroup(aFlag )


-The parameter is if the group shall be a transport group or not. ‘True’ means it’s a transport group. It is ‘False by default’.


We add another group, grpVillage3, in which we add two Russian trucks, to transport infantry with.

mapvars.grpVillageRu3 = CreateGroup( 'grpVillageRu3', [ USSR_TRUCK, USSR_TRUCK ], 'areaVillageSpawn2', PLAYER_SCRIPT, TEAM_USSR  )      


We create the infantry units with ‘CreateSquad’ and we want to have two squads. CreateSquad is perfect to use when we want to have control over which units that belongs to which squad. We send a list of units we want the squad to have and on what position the squad should spawn. We can send in other units than infantry but it is not recommended.


mapvars.grpVillageRu3.CreateSquad( [ USSR_MARINE, USSR_MARINE, USSR_MACHINE_GUNNER, USSR_ANTITANK ], 'areaVillageSpawn2' )
mapvars.grpVillageRu3.CreateSquad( [ USSR_MARINE, USSR_MARINE, USSR_MACHINE_GUNNER, USSR_ANTITANK ], 'areaVillageSpawn2' )


(And yes, this is the same code twice; it’s not a copy + paste error!)

Because we have the infantry and transport vehicle in the same group, we use ‘None’ as the first parameter in ‘EnterGroup’ and we want them to enter the transport instantly i.e. the second parameter should be ‘True’.

mapvars.grpVillageRu3.EnterGroup( None, True )


To make grpVillageRu3 a ‘transporter group’ we use True as parameter in ‘SetTransporterGroup’.

mapvars.grpVillageRu3.SetTransporterGroup( True )

Now that we have a group with two trucks that each have a squad loaded lets give them some PostCommands.

Post commands on a group

PostCommands are used to give the group a queue of orders. The orders will be executed in the order that they where added. Both attack and base behaviors use PostCommands and there are three different types, CMD_ATTACK, CMD_PRIMARY and CMD_BASE. It’s set to CMD_PRIMARY by default.


PostCommand(aCommand, aType = CMD_PRIMARY )

-The first parameter is the command that we want to add to the group.

-The second parameter is what priority the command shall have. By default its set to CMD_PRIMARY.


To remove all commands from a group we use the ClearCommands method.


ClearCommands( aType = CMD_PRIMARY )

-The parameter is the command type to remove.


Some of the group’s methods also exist as commands. The commands starts with ‘CMD_’ and you can check them out here. Wic\pyhon\groups\command.py


We want the grpVillageRu3 to defend the ’CP_Village’ command point so we will add some post commands. We will move them to the command point then unload and set the attack and base behavior.


To give the group a move order we will use the command CMD_MoveGroup, we send in the position where the group shall move to and that it is enough to get into a 50 units radius from the point to count as done.

mapvars.grpVillageRu3.PostCommand( CMD_MoveGroup( 'CP_Village', 50 ) )

When the group is near enough we want the infantry to exit the transport vehicle. We use the CMD_UnloadAll command.


mapvars.grpVillageRu3.PostCommand( CMD_UnloadAll( ) )


To prevent possible problems we make sure that the group is not a transporter group any more by setting it to False.


mapvars.grpVillageRu3.PostCommand( CMD_SetTransporterGroup( False ) )


There’s no big difference in how you give the group attack and base behavior with or without PostCommand. We want the group grpVillageRu3 to have the attack behavior BHA_Aggressive. With aggressive as attack behavior the group will try to surround their attacker. As base behavior we’ll use the ‘idle units’ which will make them idle around the command point ’CP_Village’.

mapvars.grpVillageRu3.PostCommand( CMD_SetAttackBehavior( BHA_Aggressive( ) ) )
mapvars.grpVillageRu3.PostCommand( CMD_SetBaseBehavior( BHB_IdleUnits( 'CP_Village' ) ) )

Enter buildings with a group

If we want to have units in a building it works pretty much the same way as when entering transports. The method we use is EnterBuilding and it takes the name of a building or a list of buildings that we want the squads to enter. It also possibly for the units to instant enter the buildings.


Receive the name of buildings

To get the name of a building we have to select the building in WICEd and click on the Placed tab where the selected buildings name will be highlighted. Then it’s just to copy the name or remember it and use it in the code.

EnterBuilding(aBuilding, aInstantEnter = False )

-The first parameter is the name of a building or a list of buildings for the infantry units in the group to enter.

-The second parameter is if they shall enter the building instantly.


We could also use the method EnterContainer that works on both transport vehicles and buildings. But if we use ‘EnterContainer’ we can’t use more than one transport unit or building.


EnterContainer(aContainer, aInstantEnter = False )


-The first parameter is the name of a building or an id of a transport unit.

-The second parameter is if the squad shall enter the container instantly. By default it is ‘False’ which means that the squad has to get close to the container before it enters.


Now let us create a group that has three squads, with two infantry units each, and place them inside three of the buildings in the village.


We start by creating an empty group, grpVillageBuildings, so we don’t send in any units in the list.


mapvars.grpVillageBuilding = CreateGroup( 'grpVillageBuilding', [ ], None, PLAYER_SCRIPT, TEAM_USSR)


Now we add the three squads to the group.

mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )
mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )
mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )

And last we use the EnterBuilding method and send in the list of buildings and set the second parameter to true because we want them to instant enter the buildings.


mapvars.grpVillageBuilding.EnterBuilding( [ 'CountryHouse_03__3', 'CountryHouse_01__2', 'CountryHouse_03__2' ], True )


So this is the code we add to the Village function in allunits.py.

# Create a group that has three squads that we enter in to three buildings.
mapvars.grpVillageBuilding = CreateGroup( 'grpVillageBuilding', [ ], None, PLAYER_SCRIPT, TEAM_USSR  )
mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )
mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )
mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )
mapvars.grpVillageBuilding.EnterBuilding( [ 'CountryHouse_03__3', 'CountryHouse_01__2', 'CountryHouse_03__2' ], True )

Create a platoon

A platoon consists of one or more groups and are useful to check several groups size or if all units in the platoon are dead. By default the platoon will trigger all groups attack behavior when one group gets engaged in combat. We can turn that off if we want, by making sure the platoon is not a combat platoon.

We use a platoon in the chapter about the players starting units if you want to have a look.


Platoon( someGroups = [] )

-The first parameter is a list with the groups that we want to add to the platoon. By default it’s an empty list and means that we will be adding groups to the platoon later.


When we want to add a group to an already existing platoon we use the AddGroup method, it will add one group at a time.


AddGroup( aGroup )

-The parameter is the group that shall be added to the platoon.


To remove a group from the platoon there is a RemoveGroup method.


RemoveGroup( aGroup )


-The parameter is the group that shall be removed from the platoon. If the group isn’t in the platoon the game will crash.


To change if the platoon shall be a combat platoon or not we use SetCombatPlatoon.


SetCombatPlatoon( aCombatFlag )

-The parameter is if the platoon shall be a combat platoon.


If we want to get all groups that are in a platoon we have to use the member myGroups that will return a list with all the groups.


groupsInThePlatoon = aPlatoon.myGroups


React on platoons

We want to show a message when the player gets engaged in combat with any of the groups at the village so we add all four groups to a platoon, pltVillage, and because we don’t want to trigger all groups attack behaviors when one of them gets engaged in we set it to not be a combat platoon.


We save the platoon in the pltVillage variable and we add all four of the Russian village groups to the platoon.


mapvars.pltVillage = Platoon( [ mapvars.grpVillageRu1, mapvars.grpVillageRu2, mapvars.grpVillageRu3, mapvars.grpVillageBuilding ] )

And set so it isn’t a combat platoon.


mapvars.pltVillage.SetCombatPlatoon( False )


This is the platoon code we will add to the Village function in allunits.py.


  1. Add all the groups in to a non combat platoon, all groups attack behavior won’t trigger if one of the
  1. groups gets in combat.


mapvars.pltVillage = Platoon( [ mapvars.grpVillageRu1, mapvars.grpVillageRu2, mapvars.grpVillageRu3, mapvars.grpVillageBuilding ] )
mapvars.pltVillage.SetCombatPlatoon( False )

canto make it possible to test if the platoon works, we’ll add a reaction that will trigger when the player gets engaged in combat with a unit in the platoon.


The reaction we will be using is RE_OnPlayerInCombatWithPlatoon.


RE_OnPlayerInCombatWithPlatoon( aPlayerId, aPlatoon, someActions )


-The first parameter is the id of the player.

-The second parameter is the platoon.

-The third is the action to execute when the player get in combat with the platoon.


So we add the RE_OnPlayerInCombatWithPlatoon reaction in the VillageStart function in the server.py file and place it at the end of the function. As player id we send in PLAYER_HUMAN and as platoon pltVillage. When it trigger it will show the message box ‘e1_3’.


RE_OnPlayerInCombatWithPlatoon(PLAYER_HUMAN, mapvars.pltVillage, Action(ShowMessageBox, 'e1_3', 103))


Don’t forget to add the message boxes in the mapname_singleplayerdata.juice file, else the game will crash. The message box will just say “We have enemy contact.” and have a homemade portrait image made from a screenshot.


MessageBoxData e1_3
{
    myType MB_TIMED
    myText "We have enemy contact."
    mySoundFile <empty>
    myVideoPortraitFile maps/europeTest/deploymentareamasks/tankDude.bik
    myPortraitText TANKDUDE
    myTimeToShow 6.0
}


Refill for the win!

If you want the player to fight pretty many units in an event but not all of them at the same time (it can look pretty hilarious with a group with 30 jeeps appearing simultaneously) the refill mode is something you will like to use, because it would be pretty boring to have to create every single unit in their own groups.

We have a very neat system that takes care of almost everything regarding refilling our groups.

More or less we just need to decide when the method will refill our groups and with what and how many, and this system will take care of the rest.


There are two ways to refill a group; the ‘normal’ way and the sometimes better ‘drop ship’ way. There are advantages and disadvantages with both methods. One of the disadvantages with drop ships are that the units will take around 20 seconds to arrive which sometimes makes it hard to have a smooth and balanced stream of units to fight.


Use the refill method

You use the ‘ActivateRefillMode’ method on a group. You must use this method on every group you want to be refilled. You don’t need to refill the group with the same units as it started with, nor the same amount or the same position.


ActivateRefillMode( aRefillLimit, aRefillAmount, aUnits, aSpawnTarget, aMoveRadius, aMoveTarget = None, aDelay = 0.0 )

1- aRefillLimit.

The first parameter is when the group will be refilled, the number of units left before the refill will be activated. For example, if we want the group to be refilled when there are 2 units left it looks like this.


mapvars.grpMansionRuAttacker1.ActivateRefillMode( 2, ‘more code will be here’ )


2- aRefillAmount.

The second parameter is how many units the group should be refilled with. For example if we want the group to contain 5 units and we want it to be refilled when 2 units are left, it will look like this.

mapvars.grpMansionRuAttacker1.ActivateRefillMode( 2, 3, ‘more code will be here’)


3- aUnits.

The third parameter is a list with the units we want the group to be refilled with. You don’t need to use the same units you used when you created the group.

If we want to refill the group with two heavy and one medium tank it would look like this.


mapvars.grpMansionRuAttacker1.ActivateRefillMode( 2, 3, [ USSR_T80U, USSR_T62], ‘more code will be here’ )


If you have less units in the list than the number you want to refill the group with like in the example above, the method will loop and start from the beginning when it reaches the end of the list. The example above will result in a refilled group containing two heavy tanks and one medium as if the list would have looked like this [USSR_T80U, USSR_T62, USSR_T80U].


If you have more units in the list than the amount of units you want to refill the group with it will simply stop when it reached the set ‘aRefillAmount’ variables limit. Next time it will be refilled it will start on the unit right after where it stopped the last time. If it reaches the end of the list before the ‘aRefillAmount’ limit is reached, it will continue from the start again.


Here is a group that will be refilled with a different couple of units.


mapvars.grpMansionRuAttacker1.ActivateRefillMode( 2, 2, [USSR_MARINE, USSR_JEEP, USSR_MI8_HIP], ‘more code will be here’ )


The first time the group will be refilled it will be with one Marine and one Jeep, as if the list would look like this [USSR_MARINE, USSR_JEEP].

Next time the same group will be refilled it will be with one Hip and one Marine, as if the list would look like this [USSR_MI8_HIP, USSR_MARINE].

The third time the same group will be refilled it will be with one Jeep and one Hip, as if the list would look like this [USSR_JEEP, USSR_MI8_HIP].

And so on.


4- aSpawnTarget.

The fourth parameter, aSpawnTarget, is the area where you want the refilled units to spawn. It don’t have to be the same position that the group used when you created it.


mapvars.grpMansionRuAttacker1.ActivateRefillMode( 2, 3, [ USSR_T80U, USSR_T62, USSR_BMP_3 ], 'areaRuSpawn2', ‘more code will be here’)


5- aMoveRadius.

The fifth parameter works if you have ‘aMoveTarget’. If you have a target this variable decides how close to that target the group must be to count as finished. You always have to set this variable to something even if the next parameter is set to None. And the next parameter, aMoveTarget, should always be None, so it really doesn’t matter what you write here. J


mapvars.grpMansionRuAttacker1.ActivateRefillMode( 2, 3, [ USSR_T80U, USSR_T62, USSR_BMP_3 ], 'areaRuSpawn2', 5, ‘more code will be here’ )


6- aMoveTarget. The sixth parameter is a position the units move to when spawned (this is an old solution; this should be done with a post refill command instead). This variable should be set to None.


mapvars.grpMansionRuAttacker1.ActivateRefillMode( 2, 3, [ USSR_T80U, USSR_T62, USSR_BMP_3 ], 'areaRuSpawn2', 5, None, ‘more code will be here’)


7- aDelay.

The seventh parameter is a delay time to wait before refilling when the refillLimit is reached. In this example the group will be refilled 22 seconds after the group contains 2 units. If you have a group with just 2 units in from the beginning it will still take 22 seconds before the 3 new units will be created.


mapvars.grpMansionRuAttacker1.ActivateRefillMode( 2, 3, [ USSR_T80U, USSR_T62, USSR_BMP_3 ], 'areaRuSpawn2', 5, None, 22 )


And that was the end of the hopelessly long and complicated refill method.

(Naah, it’s not that complicated, it’s just to copy, paste and change some values really J).


Refill for the lose or how we turn of the stream of units

When you don’t want the endless stream of units anymore just use the method ‘DeactivateRefillMode’.


DeactivateRefillMode( aRemovePendingRefill):


The first and only parameter is if you want waiting units to be removed before they arrive. In the example above the units won’t arrive until 22 seconds after there only 2 units left. By default the ‘DeactivateRefillMode’ is ‘False’ which means they will arrive 22 second (as most) after you turned the refill method of. Sometimes that is a good thing but if you want the refill to be deactivated as definitely as possible you should set the parameter to True which will remove any waiting units.


def MansionEnd( ):    
    DebugMessage( 'allunits.MansionEnd::' )
    mapvars.aiPlayer2Ru.DisableBuy( )
    mapvars.grpMansionRuAttacker1.DeactivateRefillMode( )
    mapvars.grpMansionRuAttacker2.DeactivateRefillMode( True )


There’s some more methods regarding refill modes, but we usually don’t use them but if you are curious you can take a look in the wic\python\group\group.py file.

How you do to make units Invulnerable.

To make a group invulnerable you use a single line of code that looks like this.

mapvars.grpRescueArty.SetInvulnerable( True ) 

The parameter is simply a Boolean true or false. True means the group will be invulnerable. If you don’t want the group to be invulnerable no more, just use the same function but with ’False’ as parameter. If you add new units to the group they won’t be invulnerable, it is just the units that are already there when you use the function that will be affected.

Appendix

Changed files in this chapter:

Server.py

Allunits.py

Mapvars.py


Changes in the server.py file.


def RescueArtyStart( ):
    [More code here.]
 
    queRescueArtyComplete.AddObjectiveCompleted( mapvars.objRescueArty )
    queRescueArtyComplete.AddFunction( allunits.RescueArtyGetUnit )
    queRescueArtyComplete.AddEventString( 'myUnitReward' )
 
    [More code here.]


Changes in the allunits.py file.

[More code here.]
##---------------------------------------------------------------
#---------------------------  Village ---------------------------     
def Village( ):
    DebugMessage( 'allunits.Village::' )

    # Create a USSR group that are own by the script player and add an attack and base behaviour.
    mapvars.grpVillageRu1 = CreateGroup( 'grpVillageRu1', [ USSR_BMP_3 ], 'areaVillageSpawn1', PLAYER_SCRIPT, TEAM_USSR  )
    mapvars.grpVillageRu1.SetAttackBehavior( BHA_StandFast(  ) )
    mapvars.grpVillageRu1.SetBaseBehavior( BHB_IdleUnits( 'areaVillageRuMove1' ) )

    # Creates a USSR group that has two transport units, trucks. Then create two infantry squads that we
    # enter in to the trucks. We make the group a transporters group; it makes that only vehicles in the
    # group will move other wise the infantry will exit the transport when the group gets a move order.
    mapvars.grpVillageRu2 = CreateGroup( 'grpVillageRu2', [ USSR_TRUCK, USSR_TRUCK ], 'areaVillageSpawn2', PLAYER_SCRIPT, TEAM_USSR )          
    mapvars.grpVillageRu2.CreateSquad( [ USSR_MARINE, USSR_MARINE, USSR_MACHINE_GUNNER, USSR_ANTITANK ], 'areaVillageSpawn2' )
    mapvars.grpVillageRu2.CreateSquad( [ USSR_MARINE, USSR_MARINE, USSR_MACHINE_GUNNER, USSR_ANTITANK ], 'areaVillageSpawn2' )
    mapvars.grpVillageRu2.EnterGroup( None, True )
    mapvars.grpVillageRu2.SetTransporterGroup( True )

    # Move the group 50 units away from the Village CP then unload the infantry and set the attack and base behaviour.
    mapvars.grpVillageRu2.PostCommand( CMD_MoveGroup( 'CP_Village', 50 ) )
    mapvars.grpVillageRu2.PostCommand( CMD_UnloadAll( ) )
    mapvars.grpVillageRu2.PostCommand( CMD_SetAttackBehavior( BHA_Aggressive( ) ) )
    mapvars.grpVillageRu2.PostCommand( CMD_SetBaseBehavior( BHB_IdleUnits( 'CP_Village' ) ) )

    # Create a group that we sets to use cover formation on, that they will try to find position that are some what in cover.
    mapvars.grpVillageRu3 = CreateGroup( 'grpVillageRu3', [ USSR_MARINE, USSR_MARINE, USSR_AA_INFANTRY, USSR_MACHINE_GUNNER, USSR_ANTITANK ], 'areaVillageSpawn3', PLAYER_SCRIPT, TEAM_USSR  )
    mapvars.grpVillageRu3.SetFormation( FORMATION_COVER )
    mapvars.grpVillageRu3.SetAttackBehavior( BHA_Defensive(  ) )
    mapvars.grpVillageRu3.SetBaseBehavior( BHB_IdleInfantryCover( 'areaVillageRuMove1' ) )

    # Create a group that has three squads that we enter in to three buildings.
    mapvars.grpVillageBuilding = CreateGroup( 'grpVillageBuilding', [ ], None, PLAYER_SCRIPT, TEAM_USSR  )
    mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )
    mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )
    mapvars.grpVillageBuilding.CreateSquad( [ USSR_MARINE, USSR_ANTITANK ], 'areaVillageSpawn1' )
    mapvars.grpVillageBuilding.EnterBuilding( [ 'CountryHouse_03__3', 'CountryHouse_01__2', 'CountryHouse_03__2' ], True )

    # Add all the groups in to a non combat platoon, all groups attack behaviour won’t trigger if one of the groups gets in combat.
    mapvars.pltVillage = Platoon( [ mapvars.grpVillageRu1, mapvars.grpVillageRu2, mapvars.grpVillageRu3, mapvars.grpVillageBuilding ] )
    mapvars.pltVillage.SetCombatPlatoon( False )

##---------------------------------------------------------------
#-------------------------  RescueArty  -------------------------     
def RescueArty( ):
    DebugMessage( 'allunits.RescueArty::' )
    mapvars.grpRescueArty = CreateGroup( 'grpRescueArty', [ NATO_LARS_SF_2 ], 'areaArtySpawn', PLAYER_SCRIPT, TEAM_NATO )
    mapvars.grpRescueArty.SetInvulnerable( True )
    mapvars.grpRescueArty.RegroupAt( 'areaArtySpawn', 'areaAASpawn1' )
    mapvars.grpRescueArty.SetBaseBehavior( BHB_AreaArtillery( [ Area( 'areaKillArtyFire1', 40 ), Area( 'areaKillArtyFire2', 40 ), Area( 'areaKillArtyFire3', 40 ) ], 15  ) )
    mapvars.grpRescueArtyRu1 = CreateGroup( 'grpRescueArtyRu1', [  ], , PLAYER_SCRIPT, TEAM_USSR )

def RescueArtyAttack( ):
    [More code here.]  

    mapvars.grpRescueArtyRu1.CreateUnitsAtPosition( [ USSR_BMP_R, USSR_BMP_R ], 'areaKillArtyRuSpawn' )
    mapvars.grpRescueArtyRu1.SetSpeed( 7 )
    mapvars.grpRescueArtyRu1.SetAttackBehavior( BHA_Defensive( 40 ) )
    mapvars.grpRescueArtyRu1.PostCommand( CMD_RegroupAt( 'areaKillArtyRuMove1', 'areaArtySpawn' ) )
    mapvars.grpRescueArtyRu1.PostCommand( CMD_SetBaseBehavior( BHB_HoldPosition( 'areaKillArtyRuMove1' ) ) )

def RescueArtyGetUnit( ):
    DebugMessage( 'allunits.RescueArtyGetUnit::' )

    # Remove all behavior from the group
    mapvars.grpRescueArty.Purge( )

    # Give the unit to the player 
    mapvars.grpRescueArty.SetOwner( PLAYER_HUMAN )


Changes in the mapvars.py file.

##---------------------------------------------------------------
#---------------------------  Village ---------------------------

reactVillagePlayerDead = None
 
grpVillageRu1 = None
grpVillageRu2 = None
grpVillageRu3 = None
grpVillageBuilding = None
pltVillage = None
Chapter 10: Event string < > Chapter 11b: The Unittypes List
Personal tools
User Created Content