Bos Wars Scripting API: UnitType


Stratagus FAQ PREV NEXT LUA Index
DefineAnimations DefineBoolFlags DefineVariables DefineUnitStats DefineUnitType

Intro - Introduction to unit-type functions and variables

Everything around the C UnitType structure.

Functions

DefineAnimations("ident-name", {type = {script}, ...})

Define animations.
"ident-name"
Name of the animation to define. The name tells stratagus when to play the animation.
type
Supported types:
script
A script is a list of operations. Supported operations:

Example

DefineAnimations("animations-footman", {
  Still = {"frame 0", "wait 4", "frame 0", "wait 1",},
  Move = {"unbreakable begin", "frame 0", "move 3", "wait 2", "frame 5", "move 3", "wait 1",
    "frame 5", "move 3", "wait 2", "frame 10", "move 2", "wait 1",
    "frame 10", "move 3", "wait 1", "frame 0", "move 2", "wait 1",
    "frame 0", "move 3", "wait 2", "frame 15", "move 3", "wait 1",
    "frame 15", "move 3", "wait 2", "frame 20", "move 2", "wait 1",
    "frame 20", "move 3", "wait 1", "frame 0", "move 2", "unbreakable end", "wait 1",},
  Attack = {"unbreakable begin", "frame 25", "wait 3", "frame 30", "wait 3", "frame 35", "wait 3",
    "frame 40", "attack", "sound footman-attack", "wait 5", "frame 0", "wait 10",
    "frame 0", "unbreakable end", "wait 1",},
  Death = {"unbreakable begin", "frame 45", "wait 3", "frame 50", "wait 3", "frame 55", "wait 100",
    "frame 55", "unbreakable end", "wait 1",}

DefineBoolFlags( "flag-1", "flag-2", ...)

Define boolean unit flags. Examples are organic, mechanical, undead, etc. Spells use these to determine who to hit, and units can be restricted too. Try to avoid using names with other meanings (nothing from spell condition definition.) Some Flags are already defined in the engine : the UnitType flags. So following flags are the value of the unitType : "Building", "BuilderOutSide", "BuilderLost", "ShoreBuilding", "Coward", "Harvester", "Revealer", "LandUnit", "AirUnit", "SeaUnit", "ExplodeWhenKilled", "VisibleUnderFog", "PermanentCloack", "AttackFromTransporter", "GroundAttack", "CanAttack", "CanHarvest", "Vanishes", "Flip", "Decoration", "IsNotSelectable", "SelectableByRectangle", "Indestructible".

Example

    DefineBoolFlags("organic", "hero", "mechanical", "undead", "demonic", "angelic")

DefineVariables( "varname-1", {tag = value}, "varname-2", {tag = value}, ...)

Define variable for unit. Spells could use these to determine who to hit, and units can be restricted too. Try to avoid using names with other meanings (nothing from unit definitions or spell condition definition). tag = value represent default value for UnitType. These values can be overwritten in UnitType definition.
Value = number
Initial value for the variable
Max = number
Max value for the number, assuming 0 is the min.
Increase = number
Number to add each second if possible, negative value are possible.
Enable = boolean
if the variable is active by default. For example, Mana is active only for caster, but HP is available for every unit.

Note

Some variables are predefined and could be used with some restriction. You cannot modify their values, there are readonly (but no errors are generated), So see DefineUnit() for initialise them (some variables are computed in play and be initialised). Also, the max value which is always greater than value, may have no sense or be equal at some player statistic.
The predefined values are :
HitPoints
Hp of the unit.
Build
State of the construction in building.
Mana
Mana point of the unit.
Transport
Number of unit inside (for transporter only, no build inside).
Training
Remaining cost to build the unit being training.
UpgradeTo
Time for the unit to upgrade to an other.
GiveResource
Resource that the unit gives ("resource-name" mine for exemple)
Kill
Number of unit killed by the unit.
Armor
Armor of the unit.
SightRange
Sight range of the unit.
RadarRange
Radar range of the unit.
RadarJammerRange
Radar Jamming range of the unit.
AttackRange
Attack range of the unit.
PiercingDamage
piercing damage of the unit.
BasicDamage
Basic damage of the unit.
PosX
X position of the unit. Max is the Map size.
PosY
Y position of the unit. Max is the Map size.
AutoRepairRange
Range to check for unit to repair. (for unit which can repair)
Slot
Unique number that identifies the unit (begin at 0). Max is the last valid slot number.

Example

    DefineVariable("cooldown", {Value = 0, Increase = -1, Max = 50, Enable = false})

DefineUnitType( "ident", { tag1 = value1, tag2 = value2, ...})

Define the unit types in game. A lot of the data in this struct used to be based on the UDTA section of puds, with unit statistics, but it is now a lot bigger and more configurable.
ident
The unit-type unique identifier. It is used to reference unit-types in game. F.E: "unit-knight", "unit-gold-mine". Please use all-lowercase names prefixed with unit-, it is easier to read this way.
Possible tags:
Name = "show-name"
The unit-type name shown in the game. F.E: "Knight", "Gold Mine". If the name is too long, it is split at space.
Image = {"file", filename, "size", {x, y}}
Defines the graphics used to display the unit-type in game.
Offset = {x, y}
Defines the offset for the graphics in pixels used to display the unit-type
Shadow = {tag, value, ...}
Defines the Parameters for the shadow the unit is casting in the game
Possible tags:
"file", filename
Defines the graphics used to display the shadow of the unit-type
"size", {width, height}
Defines the size of the graphics in pixels used to display the shadow of the unit-type
"offset", {x, y}
Defines the offset of the graphics in pixels used to display the shadow of the unit-type. Note that this is relative to the unit graphics including its own offset
DrawLevel = number
This is used when sorting units and missiles for drawing. Units with a higher draw order will always be on top of units with lower draw order. Units are also sorted from top to the bottom of the screen.
Animations = "animation-type"
Identifier to reference the animation sequences (scripts) for the unit-type. F.E. "animations-knight", "animations-gold-mine".
Size = {x, y}
Size of the unit-type graphic in pixels.
TileSize = {x, y}
Define the unit-type size in tiles. NOTE: currently only buildings could be bigger than one tile.
BoxSize = {width, height}
Define the size of the unit selection box. This is drawn centered around the unit and most of the time it is equal to the tile size of the unit* the size of a terrain tile, for an almost perfect fit.
NumDirections = number
Define the number of directions a unit can face. Default 1 for buildings and 8 for units. Can be adjusted from the default. Useful for rotating buildings
IsNotSelectable = boolean
set whether the unit is able to be selected or not.
Decoration = boolean
set whether the unit is a decoration (act like a tile) or not.
Indestructible = boolean
set whether the unit is indestructible not.
NeutralMinimapColor = {r, g, b}
sets the color of a unit when belonging to the neutral player. F.E. '(0 0 0) for a black oil patch.
Icon = "Icon-name"
Identifier to reference the icon shown in game for this unit-type. F.E. "icon-knight", "icon-gold-mine".
Sounds = {event, "sound-name", ...}
The following events are supported:
  • "selected": Happens when the unit is selected.
  • "acknowledge": Happens when the unit received an order.
  • "attack": Attack sound of the unit. Used when giving an attack order, it can override the acknowledge sound.
  • "ready": Happens when the unit finished training (and it's ready)
  • "repair": Happens when the unit is repairing.
  • "help": Happens when the unit is under attack.
  • "dead": Happens when the unit is killed.
You can use the same help or ready sound for all units if you want generic "Your unit is under attack", "Some unit was trained" sounds. The actual sound files are not declared here. Please see the documentation on sounds
MaxAttackRange = number
Attack range (in tiles) of this unit. Use 1 for melee units.
MinAttackRange = number
Minimum attack range (in tiles) of this unit. This is usefull for siege units you want to make vulnerable to close range attacks.
SightRange = number
Sight range (in tiles) of this unit.
RadarRange = number
Radar range of the unit.
RadarJammerRange = number
Radar Jamming range of the unit.
Armor = number
Basic armor of the unit.
BasicDamage = number
Unit's basic damage. FIXME calculations?
PiercingDamage = number
Unit's piercing damage. FIXME calculations?
RegenerationRate = number
amount of HP a unit gains per seconds
HitPoints = number
Maximum hitpoints for this Unit.
Costs = {"resource-name", amount, ...}
Define the costs to build (or aquire) this unit. F.E.: Costs = {"time", 200, "gold", 2000, "wood", 1000, "oil", 200}
RightMouseAction = "none" or "move" or "attack" or "harvest" or "spell-cast" or "sail"
"none"
Do nothing.
"move"
Right clicking defaults to move. This should be used for unit's that can't attack.
"attack"
Right clicking defaults to attack. This should be used for most combat units.
"harvest"
This should be used for resource gathering units. It will return goods when on a deposit and mine when on a resource.
"spell-cast"
This is an ugly hack for demolishing units. The unit will cast it's first known spell(in order of spell definition) instead of attacking a hostile unit.
GivesResource = resource-name
This will make the unit (normally a building) a resource (sugar mine, geyser, etc). It's followed by a resource ident F.E. "gives-resource", "gold"
CanHarvestFrom = boolean
This is a flag for harvestable resource buildings.
CanStore = {resource-name, ...}
This flag makes the unit a resource storage, units will come here and unload their cargo. It's followed by a list of accepted resource identifiers. F.E. can-store '(stone coal)
Building = boolean
Unit is a building, and imobile. Available as a spell target check.
VisibleUnderFog = boolean
Unit remains visible under fog of war. In most games this is true for and only for buildings.
ShoreBuilding = boolean
Unit is a shore building, and imobile. This is used for those unique buildings that have to be build on sea and have at least one point on coast.
BuilderOutside
true if the builder builds a building from the outside
BuilderLost
true if you would like the builder to die once the building has been completed (used for morphing into a building)
AutoBuildRate
The rate at which the building builds itself NOT IMPLEMENTED
BuildingRules = { { "distance", { Distance = 3, DistanceType = ">", Type = "unit-gold-mine"}}}
BuildingRules allows you to specify a list of restrictions to make when building. The list is in nested tables, the inter list is and'd together, and or'd with the other lists. See the example for details.
"distance"
Specifies a distance constraint.
Distance
The distance in tiles to measure
DistancType
<, >, <=, >=, ==, !=
Type
The type of the unit that this distance restriction applies to
Except NOT IMPLEMENTED
boolen, #t implies all units, except this type must be
"addon"
Specifies an addon to an existing building.
OffsetX
Offset from the top left of the parent building that this unit must be placed. eg, -2 would left two of the building. (you need to consider the size of the parent building)
OffsetY
As with OffsetX, except in the Y direction
Type
Type of the unit that this unit is an addon too
"tile" NOT IMPLEMENTED
Implement a tile restriction, unit must be placed on certain types of tiles.
NumberOnMask
The number of tiles that are needed until the build of a type to satisfy
Mask
Mask of the tiles that needs to be meet Will be updated to tiletype
"ontop"
Building must be built on top of another building type NOTE: the engine may not be able to guess the correct parent if the rules are complex enough.
Type
The unit-type that we are to build on top of
ReplaceOnDie
boolean, true if you want the original unit to be replaced when this unit dies
ReplaceOnBuild
boolean, true if you want to remove the old unit underneath when you build this one
"direction" NOT IMPLEMENTED
Direction
A bitmask in int format for the directions to build. (bits not specified yet)
Coward = boolean
Unit will not attack on sight, and will run away instead of retaliating. Use this for units that can't attack or are next to useless in combat (like resource workers) Available as a spell target check.
CanCastSpell = {spell-name, ...}
This is used to determine what spells can this unit cast. It is followed by a list of spell names. Spells have to be declared already. Since some spells also rely on units being defined this can lead to a chicken and egg problem. It's better to declare an unit type in advance with just DefineUnitType( "unit-whatever", {}). Please see the documentation on spells. F.E. CanCastSpell = {"spell-healing", "spell-exorcism"}
RepairRange = number
Range that a unit can repair from, eg. RepairRange = 1.
AutoRepairRange = number
Range to check for unit to repair. (for unit which can repair)
RepairHp = number
Defines the amount of hp a unit gain for each repair animation. Units can only be repaired if this value is non-zero. F.E.: RepairHp = 4.
RepairCosts = {resource-name, cost, ...}
Define the costs to repair this unit. F.E.: RepairCosts = {"gold", 2, "wood", 1, "oil", 1 )
PermanentCloak = boolean
Unit is permanently cloaked, and can only be seen by detectors (see below.)
DetectCloak = boolean
Unit can detect cloaked units. If an unit is detected other units can attack it as well\
RandomMovementProbablitity = number
When the unit is idle this is the probability that it will take a step in a random direction, in percents. Usefull for neutral animals.
ClicksToExplode = number
If this is non-zero, then after that many clicks the unit will commit suicide. Doesn't work with resource workers/resources.
ComputerReactionRange = number
This is supossed to be the reaction range for AI units, but it is not used.
PersonReactionRange = number
This is supossed to be the reaction range for human player units, but it is not used.
Priority = number
This is the ai priority level. High damage low-hp units for instancce should have higher priorities than say a peasant. It can be safely ignored.
AnnoyComputerFactor = number
This is another ai priority level. This is not used, but included in wc2 data. Maybe it should be used to attack resource buildings first? You can safely ignore it.
Decay = number
This is the unit's decay rate, in 1/6 seconds. It should be really really really changed to cycles. If you set this the unit will die by itself after a while. Don't use it for spells, spells will override this with their own ttl setting.
BurnPercent = number
The unit will start burning when it has less health than this, in percents.
BurnDamageRate = number
The rate at which the unit will get damaged. The period is the same as with regeneration.
Points = number
This is the score value of an unit. Used for the final score.
Missile = missile-name
Some units fire by throwing missiles, this is the missile thrown. You can use it for close range units as well, but I can't really see the point.
Corpse = {unittype-name, number}
This is the corpse of the unit. When the unit dies and passes through it's death animation it turns into this. It's a list of an unit-name and a a corpse frame number. As you can see in DefineAnimations(), an animation is composed out of several script frames, this is the frame to start the script from. FE: Corpse = {"unit-dead-body", 0}
ExplodeWhenKilled = missile-name
Sets unit to explode when killed, syntax is followed by the missile to use. eg. ExplodeWhenKilled "missile-explosion"
DeathExplosion = explosion-function
Set the lua function that will create the particles of the explosion.
AttackFromTransporter = boolean
Gives units with range the ability to attack from within a transporter such as a building. These can act like amoured personnel carriers or bunkers
CanTransport = {flag, "true" or "only" or "false", ...}
Unit is a transporter, you can place units with good flag inside.
Note: If you want the unit to be able to transport all land unit, use CanTransport = {}.
Note: you really should add an unload button for transporters.
Note: flag must be defined before with DefineBoolFlags()
MaxOnBoard = number
This is only used for transporters, It's the maximum allowed on board. Curently you can't have more that 6, or you won't get any buttons for the rest.
Revealer = boolean
This is a special flag to use for reveal map spells. A reveal map smell is in fact a summon spell with an infinite range, that summons an unit with the revealer flag. Revealer are summoned and marked removed, but they still keep their sight. This way a revealer unit can't be attacked, won't show on the minimap and can't be interacted with. Please see the documentation on spells.
SelectableByRectangle = boolean
Most units should have this flag. When false the unit will only get selected alone, use this for buildings. Enemy units are never selectable by rectangle.
flags = boolean
You can add a bunch of flags, defined with DefineBoolFlags() You can add how many flags you would like, but keep in mind that you have to call DefineBoolFlags() before.
variable = {tag = value , ...} or number or boolean
You can add a bunch variable, defined with DefineVariables() You can add how many flags you would like, but keep in mind that you have to call DefineVariables() before. You can overwrite each tag/value by the same method you use for DefineVariables() or simply Enable/disable it with a boolean, or set Max and value with a number
CanTargetFlag = {flag, "true" or "only" or "false", ...}
This allows check for targetting similar to spell conditions. By default everything is set to true, so you can target everything. Only means that you can only fire units with that flag, and false only units without that flag.
FIXME: continue documentation.
FIXME: continue documentation.

Example

Sorry, but due to the huge number of available flags we can only show a limited example.
DefineUnitType("unit-footman", { Name = "Footman",
  Image = {"file", "alliance/units/footman.png", "size", {72, 72}},
  Animations = "animations-footman", Icon = "icon-footman",
  Costs = {"time", 60, "gold", 600},
  Speed = 10, -- Variable Defined
  HitPoints = 60,
  DrawLevel = 40,
  TileSize = {1, 1}, BoxSize = {31, 31},
  SightRange = 4, ComputerReactionRange = 6, PersonReactionRange = 4,
  Armor = 2, BasicDamage = 6, PiercingDamage = 3, Missile = "missile-none",
  MaxAttackRange = 1,
  Priority = 60,
  Points = 50,
  Demand = 1,
  Corpse = {"unit-dead-body", 6},
  Type = "land",
  RightMouseAction = "attack",
  CanAttack = true,
  CanTargetLand = true,
  LandUnit = true,
  organic = true,
  SelectableByRectangle = true,
  -- distance is >3 from gold, and <2 from a watch tower
  -- or distance is >6 from goldmine
  BuildingRules = { { "distance", { Distance = 3, DistanceType = ">", Type = "unit-gold-mine"},
  					  "distance", { Distance = 2, DistanceType = "<", Type = "unit-gold-mine"}},
					{ "distance", { Distance = 6, DistanceType = ">", Type = "unit-gold-mine"},
					}
				  },
  Sounds = {
    "selected", "footman-selected",
    "acknowledge", "footman-acknowledge",
    "ready", "footman-ready",
    "help", "basic alliance voices help 1",
    "dead", "basic alliance voices dead",
    "attack", "footman-attack"} } )

All trademarks and copyrights on this page are owned by their respective owners.
(c) 2002-2007 by The Bos Wars Project