File: unittype.html

package info (click to toggle)
boswars 2.8-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 96,652 kB
  • sloc: cpp: 57,250; python: 1,715; sh: 25; makefile: 17
file content (976 lines) | stat: -rw-r--r-- 41,404 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head>
<!--
----	(c) Copyright 2002-2007 by Lutz Sammer, Russell Smith

----    This program is free software; you can redistribute it and/or modify
----    it under the terms of the GNU General Public License as published by
----    the Free Software Foundation; only version 2 of the License.
----
----    This program is distributed in the hope that it will be useful,
----    but WITHOUT ANY WARRANTY; without even the implied warranty of
----    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
----    GNU General Public License for more details.
----
----    You should have received a copy of the GNU General Public License
----    along with this program; if not, write to the Free Software
----    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
----    02111-1307, USA.
-->
    <title>Bos Wars Scripting API: UnitType</title>
    <meta http-equiv="Content-Type" content="text/html; CHARSET=iso-8859-1">
    <link rel="stylesheet" type="text/css" href="scripts.css">
</head>
<body>
    <h1>Bos Wars Scripting API: UnitType</h1>
<hr>
<a href="../index.html">Bos Wars</a> 
<a href="../faq.html">FAQ</a> 
<a href="ui.html">PREV</a> 
<a href="ai.html">NEXT</a> 
<a href="index.html">LUA Index</a>
<hr>
<a href="#DefineAnimations">DefineAnimations</a>
<a href="#DefineVariables">DefineVariables</a>
<a href="#DefineUnitType">DefineUnitType</a>
<a href="#frame_numbers">frame numbers</a>
<hr>
<h2>Intro - Introduction to unit-type functions and variables</h2>

Everything around the C UnitType structure.

<h2>Conceptual</h2>

<a name="frame_numbers"></a>
<h3>Frame numbers and flipping</h3>

<p>The engine draws units and missiles using frames that it loads from
graphic files.  The frames within a file all have the same size and
are numbered from zero up.  When a unit or a missile moves, the engine
tries to automatically choose a frame that faces the correct direction.</p>

<table border="1">
  <caption>Example: unit with Flip = false, NumDirections = 8</caption>
  <colgroup span="1">
  <colgroup span="8">
  <tr>
    <th></th>
    <th colspan="8">All frames are in the graphic file.</th>
  </tr>
  <tr>
    <th></th>
    <th>N</th>
    <th>NE</th>
    <th>E</th>
    <th>SE</th>
    <th>S</th>
    <th>SW</th>
    <th>W</th>
    <th>NW</th>
  </tr>
  <tr>
    <th>still</th>
    <td>frame 0</td>
    <td>frame 1</td>
    <td>frame 2</td>
    <td>frame 3</td>
    <td>frame 4</td>
    <td>frame 5</td>
    <td>frame 6</td>
    <td>frame 7</td>
  </tr>
  <tr>
    <th>death step 1</th>
    <td>frame 8</td>
    <td>frame 9</td>
    <td>frame 10</td>
    <td>frame 11</td>
    <td>frame 12</td>
    <td>frame 13</td>
    <td>frame 14</td>
    <td>frame 15</td>
  </tr>
  <tr>
    <th>death step 2</th>
    <td>frame 16</td>
    <td>frame 17</td>
    <td>frame 18</td>
    <td>frame 19</td>
    <td>frame 20</td>
    <td>frame 21</td>
    <td>frame 22</td>
    <td>frame 23</td>
  </tr>
</table>

<pre class="lua">
<a href="#DefineAnimations">DefineAnimations</a>("animations-example", {
    Still = {"frame 0", &hellip;},
    Death = {&hellip;, "frame 8", &hellip;, "frame 16", &hellip;}})
</pre>

<p>To save effort and memory, the frames that face the west can be
omitted from the graphic file.  The engine will then generate them
on demand by flipping the corresponding frames that face the east.
To enable this feature, set <code>Flip = true</code>
in <a href="#DefineUnitType">DefineUnitType</a>
or <a href="magic.html#DefineMissileType">DefineMissileType</a>.</p>

<p>Flipping changes the numbers of frames.  Only the frames that
are left in the graphic file have contiguous nonnegative numbers.
Each flipped frame has a negative number that the engine computes as
(-1 - <var>original number</var>).</p>

<table border="1">
  <caption>Example: unit or missile with Flip = true, NumDirections = 8</caption>
  <colgroup span="1">
  <colgroup span="5">
  <colgroup span="3" style="background: #eee">
  <tr>
    <th></th>
    <th colspan="5">These frames are in the graphic file.</th>
    <th colspan="3">Not in the file.  Flipped at run time.</th>
  </tr>
  <tr>
    <th></th>
    <th>N</th>
    <th>NE</th>
    <th>E</th>
    <th>SE</th>
    <th>S</th>
    <th>SW</th>
    <th>W</th>
    <th>NW</th>
  </tr>
  <tr>
    <th>still</th>
    <td>frame 0</td>
    <td>frame 1</td>
    <td>frame 2</td>
    <td>frame 3</td>
    <td>frame 4</td>
    <td>frame -4 flipped from 3</td>
    <td>frame -3 flipped from 2</td>
    <td>frame -2 flipped from 1</td>
  </tr>
  <tr>
    <th>death step 1</th>
    <td>frame 5</td>
    <td>frame 6</td>
    <td>frame 7</td>
    <td>frame 8</td>
    <td>frame 9</td>
    <td>frame -9 flipped from 8</td>
    <td>frame -8 flipped from 7</td>
    <td>frame -7 flipped from 6</td>
  </tr>
  <tr>
    <th>death step 2</th>
    <td>frame 10</td>
    <td>frame 11</td>
    <td>frame 12</td>
    <td>frame 13</td>
    <td>frame 14</td>
    <td>frame -14 flipped from 13</td>
    <td>frame -13 flipped from 12</td>
    <td>frame -12 flipped from 11</td>
  </tr>
</table>

<pre class="lua">
<a href="#DefineAnimations">DefineAnimations</a>("animations-example", {
    Still = {"frame 0", &hellip;},
    Death = {&hellip;, "frame 5", &hellip;, "frame 10", &hellip;}})
</pre>

<p>In missiles, the engine always numbers frames as if
<a href="magic.html#DefineMissileType.Flip">Flip</a> were true.</p>

<table border="1">
  <caption>Example: missile with Flip = false, NumDirections = 8, Frames = 3*5</caption>
  <colgroup span="1">
  <colgroup span="5">
  <colgroup span="3" style="background: #eee">
  <tr>
    <th></th>
    <th colspan="8">All frames are in the graphic file.</th>
  </tr>
  <tr>
    <th></th>
    <th>N</th>
    <th>NE</th>
    <th>E</th>
    <th>SE</th>
    <th>S</th>
    <th>SW</th>
    <th>W</th>
    <th>NW</th>
  </tr>
  <tr>
    <th>animation step 0</th>
    <td>frame 0</td>
    <td>frame 1</td>
    <td>frame 2</td>
    <td>frame 3</td>
    <td>frame 4</td>
    <td>frame -4</td>
    <td>frame -3</td>
    <td>frame -2</td>
  </tr>
  <tr>
    <th>animation step 1</th>
    <td>frame 5</td>
    <td>frame 6</td>
    <td>frame 7</td>
    <td>frame 8</td>
    <td>frame 9</td>
    <td>frame -9</td>
    <td>frame -8</td>
    <td>frame -7</td>
  </tr>
  <tr>
    <th>animation step 2</th>
    <td>frame 10</td>
    <td>frame 11</td>
    <td>frame 12</td>
    <td>frame 13</td>
    <td>frame 14</td>
    <td>frame -14</td>
    <td>frame -13</td>
    <td>frame -12</td>
  </tr>
</table>

<pre class="lua"><a href="magic.html#DefineMissileType">DefineMissileType</a>("missile-example", {
    Flip = false,
    NumDirections = 8,
    Frames = 3*5,       -- Not 3*8, even though all frames are in the file.
    &hellip;})
</pre>

<h2>Functions</h2>
<a name="DefineAnimations"></a>
<h3>DefineAnimations("ident-name", {type = {script}, ...})</h3>

Define animations.

<dl>
<dt>"ident-name"</dt>
<dd>Name of the animation to define. The name tells stratagus when to play the
animation.</dd>
<dt>type</dt>
<dd>Supported types:
    <ul>
    <li>Still</li>
    <li>Move</li>
    <li>Attack</li>
    <li>Repair</li>
    <li>Train</li>
    <li>Build</li>
    <li>Harvest_ followed by the name of the harvested resource</li>
    <li>Death</li>
    </ul>
</dd>
<dt>script</dt>
<dd>
	A script is a list of operations. Supported operations:
	<ul>
	<li>"frame X": Display this frame (see <a href="#frame_numbers">Frame numbers and flipping</a>) plus the direction offset</li>
	<li>"exact-frame X": Display this exact frame</li>
	<li>"wait X": Wait this number of cycles</li>
	<li>"random-wait X Y": Wait a random number of cycles between X and Y</li>
	<li>"sound X": Play this sound</li>
	<li>"random-sound X Y Z ...": Randomly play one of the listed sounds</li>
	<li>"attack": Attack</li>
	<li>"rotate X": Rotate unit, positive for clockwise, negative for counterclockwise</li>
	<li>"random-rotate X": Rotate in a random direction</li>
	<li>"move X": Move this number of pixels</li>
	<li>"unbreakable {begin|end}": Start or end an unbreakable section</li>
	<li>"label X": Create a label (used by goto and random-goto)</li>
	<li>"goto X": Goto a label position</li>
	<li>"random-goto X Y": Goto label Y with X percent probability</li>
</dd>
</dl>

<h4>Example</h4>

<pre class="lua">
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",}
</pre>

<a name="DefineVariables"></a>
<h3>DefineVariables( "varname-1", {tag = value}, "varname-2", {tag = value}, ...)</h3>

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.

<dl>
  <dt>Value = number</dt>
  <dd>Initial value for the variable</dd>
  <dt>Max = number</dt>
  <dd>Max value for the number, assuming 0 is the min.</dd>
  <dt>Increase = number</dt>
  <dd>Number to add each simulated second if possible, negative value are possible.</dd>
  <dt>Enable = boolean</dt>
  <dd>if the variable is active by default.
For example, Mana is active only for caster, but HP is available for every unit.
When a variable is disabled, the Increase does not take effect,
and the Value usually becomes invisible (but see
<a href="config.html#DefineDecorations.ShowIfNotEnable">ShowIfNotEnable in DefineDecorations</a>).
</dd>
</dl>

<h4 id="predefined-variables">Note</h4>
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 <a href="#DefineUnitType">DefineUnitType()</a> 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.<br>
The predefined values are :
<dl>
  <dt id="variable.HitPoints">HitPoints</dt>
  <dd>Hp of the unit.</dd>
  <dt id="variable.Build">Build</dt>
  <dd>State of the construction in building.</dd>
  <dt id="variable.Mana">Mana</dt>
  <dd>Mana point of the unit.</dd>
  <dt id="variable.Transport">Transport</dt>
  <dd>Number of unit inside (for transporter only, no build inside).</dd>
  <dt id="variable.Training">Training</dt>
  <dd>Remaining cost to build the unit being training.</dd>
  <dt id="variable.GiveResource">GiveResource</dt>
  <dd>Resource that the unit gives ("resource-name" mine for exemple)</dd>
  <dt id="variable.Kill">Kill</dt>
  <dd>Number of unit killed by the unit.</dd>
  <dt id="variable.Armor">Armor</dt>
  <dd>Basic armor of the unit.</dd>
  <dt id="variable.SightRange">SightRange</dt>
  <dd>Sight range (in tiles) of the unit.
    See also <a href="config.html#Preference.ShowSightRange">Preference.ShowSightRange</a>.</dd>
  <dt id="variable.RadarRange">RadarRange</dt>
  <dd>Radar range of the unit.</dd>
  <dt id="variable.RadarJammerRange">RadarJammerRange</dt>
  <dd>Radar Jamming range of the unit.</dd>
  <dt id="variable.AttackRange">AttackRange</dt>
  <dd>Attack range of the unit.
    See also <a href="config.html#Preference.ShowAttackRange">Preference.ShowAttackRange</a>.</dd>
  <dt id="variable.PiercingDamage">PiercingDamage</dt>
  <dd>piercing damage of the unit. FIXME calculations?</dd>
  <dt id="variable.BasicDamage">BasicDamage</dt>
  <dd>Basic damage of the unit. FIXME calculations?</dd>
  <dt id="variable.PosX">PosX</dt>
  <dd>X position of the unit. Max is the Map size.</dd>
  <dt id="variable.PosY">PosY</dt>
  <dd>Y position of the unit. Max is the Map size.</dd>
  <dt id="variable.AutoRepairRange">AutoRepairRange</dt>
  <dd>Range to check for unit to repair. (for unit which can repair)<dd>
  <dt id="variable.Slot">Slot</dt>
  <dd>Unique number that identifies the unit (begin at 0). Max is the last valid slot number.</dd>
</dl>

<h4>Example</h4>

<pre class="lua">
DefineVariable("cooldown", {Value = 0, Increase = -1, Max = 50, Enable = false})
</pre>

<a name="DefineUnitType"></a>
<h3>DefineUnitType( "ident", { tag1 = value1, tag2  = value2, ...})</h3>

    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.

<dl>
<dt>ident</dt>
<dd>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.
</dd>
</dl>
Possible tags:
<dl>
<dt>Name = "show-name"</dt>
<dd>The unit-type name shown in the game. F.E: "Knight", "Gold Mine".
If the name is too long, it is split at space.
</dd>
<dt id="DefineUnitType.Image">Image = {"file", filename, "size", {x, y}}</dt>
<dd>Defines the graphics used to display the unit-type in game.</dd>
<dt>Offset = {x, y}</dt>
<dd>Defines the offset for the graphics in pixels used to display the unit-type</dd>
<dt>Shadow = {tag, value, ...}</dt>
<dd>Defines the Parameters for the shadow the unit is casting in the game</dd>
<dd>Possible tags:
<dl>
<dt>"file", filename</dt>
<dd>Defines the graphics used to display the shadow of the unit-type</dd>
<dt>"size", {width, height}</dt>
<dd>Defines the size of the graphics in pixels used to display the shadow of the unit-type</dd>
<dt>"offset", {x, y}</dt>
<dd>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</dd>
</dl></dd>
<dt>Flip = boolean</dt>
<dd>Flip = false (the default) means the unit type has separate frames
for all directions.  The graphic file defined with the
<a href="#DefineUnitType.Image">Image</a> tag must thus have
<a href="#DefineUnitType.NumDirections">NumDirections</a> frames
for each animation posture.</dd>
<dd>Flip = true means the frames facing west are not included in the
graphic file because they are mirror images of the frames facing east.
The file must then have only <var>NumDirections</var> / 2 + 1 frames
for each animation posture.
Please see <a href="#frame_numbers">Frame numbers and flipping</a>
for details.</dd>
<dt>DrawLevel = number</dt>
<dd>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.
</dd>
<dt>Animations = "animation-type"</dt>
<dd>Identifier to reference the animation sequences (scripts) for the
unit-type. F.E. "animations-knight", "animations-gold-mine".
See <a href="#DefineAnimations">DefineAnimations</a>.
</dd>
<dt>TileSize = {x, y}</dt>
<dd>Define the unit-type size in tiles. NOTE: currently only buildings could
be bigger than one tile.
</dd>
<dt>BoxSize = {width, height}</dt>
<dd>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.
</dd>
<dt id="DefineUnitType.NumDirections">NumDirections = number</dt>
<dd>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 cannons or turrets that are considered buildings but must
aim towards the enemy.
</dd>
<dt>IsNotSelectable = boolean</dt>
<dd>set whether the unit is able to be selected or not.</dd>
<dt>Decoration = boolean</dt>
<dd>set whether the unit is a decoration (act like a tile) or not.</dd>
<dt>Indestructible = boolean</dt>
<dd>set whether the unit is indestructible not.</dd>
<dt>NeutralMinimapColor = {r, g, b}</dt>
<dd>sets the color of a unit when belonging to the neutral player. F.E. '(0 0 0) for a
black oil patch.
</dd>
<dt>Icon = "Icon-name"</dt>
<dd>Identifier to reference the icon shown in game for this unit-type.
F.E. "icon-knight", "icon-gold-mine".
</dd>
<dt>Sounds = {event, "sound-name", ...}</dt>
<dd>The following events are supported:
<dl><dd>
    <ul>
    <li>"selected": Happens when the unit is selected.
    <li>"acknowledge": Happens when the unit received an order.
    <li>"ready": Happens when the unit finished training (and it's ready)
    <li>"help": Happens when the unit is under attack.
    <li>"dead": Happens when the unit is killed.
    </ul></dd>
</dl></dd>
<dd>
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 <a href="sound.html#MakeSound">sounds</a>
</dd>
<dt>CanGroundAttack = boolean</dt>
<dd>Whether the unit can attack a place where there is no known enemy unit.
</dd>
<dt id="DefineUnitType.CanAttack">CanAttack = boolean</dt>
<dd>Whether the unit can attack at all.
</dd>
<dt id="DefineUnitType.CanTargetLand">CanTargetLand = boolean<dt>
<dd>Whether the unit can attack land units (<a href="#DefineUnitType.Type">Type</a> = "land").
Actually, it can attack naval units too, if they are explicitly allowed on land
(see <a href="#DefineUnitType.AllowTerrainLand">AllowTerrainLand</a>).
It does not matter whether the targeted unit currently is on land.
</dd>
<dt id="DefineUnitType.CanTargetSea">CanTargetSea = boolean<dt>
<dd>Whether the unit can attack naval units (<a href="#DefineUnitType.Type">Type</a> = "naval").
Actually, it can attack land units too, if they are explicitly allowed in some type of water
(see <a href="#DefineUnitType.AllowTerrainShallowWater">AllowTerrainShallowWater</a>
and <a href="#DefineUnitType.AllowTerrainDeepWater">AllowTerrainDeepWater</a>).
It does not matter whether the targeted unit currently is in water.
</dd>
<dt id="DefineUnitType.CanTargetAir">CanTargetAir = boolean<dt>
<dd>Whether the unit can attack flying units (<a href="#DefineUnitType.Type">Type</a> = "fly").
</dd>
<dt>MaxMana = number</dt>
<dd>Maximum mana of the unit.  When a unit of this type is created, it
initially has only 33% of this mana.<br>
MaxMana = <var>number</var> is equivalent to
<a href="#DefineUnitType.Mana">Mana</a> = {Initial = <var>number</var> * 33 / 100,
Max = <var>number</var>, Increase = 1, Enable = true}.
</dd>
<dt>MaxAttackRange = number</dt>
<dd>Attack range (in tiles) of this unit. Use 1 for melee units.<br>
This is the same as <a href="#variable.AttackRange">the predefined AttackRange variable</a>.
You can set it using either name.
</dd>
<dt>MinAttackRange = number</dt>
<dd>Minimum attack range (in tiles) of this unit. This is useful for siege units you
want to make vulnerable to close range attacks.
</dd>
<dt id="DefineUnitType.RegenerationRate">RegenerationRate = number</dt>
<dd>Amount of HP a unit gains per simulated second.<br>
RegenerationRate = <var>number</var> is equivalent to
<a href="#DefineUnitType.HitPoints">HitPoints</a> = {Increase = <var>number</var>}.
</dd>
<dt>EnergyValue = number</dt>
<dd>The energy cost of building or training a unit of this type.
This also affects how much energy can be harvested from the unit.
</dd>
<dt>MagmaValue = number</dt>
<dd>The magma cost of building or training a unit of this type.
This also affects how much magma can be harvested from the unit.
</dd>
<dt>MaxEnergyUtilizationRate = number</dt>
<dd>How much energy the unit can consume per simulated second,
typically when it is training or building something.
If you make this number smaller, then training will take longer.
</dd>
<dt>MaxMagmaUtilizationRate = number</dt>
<dd>How much magma the unit can consume per simulated second.
</dd>
<dt id="DefineUnitType.EnergyProductionRate">EnergyProductionRate = number</dt>
<dd>How much energy the unit produces per simulated second, just by existing.
This does not include any energy it can produce by harvesting other units.
</dd>
<dt id="DefineUnitType.MagmaProductionRate">MagmaProductionRate = number</dt>
<dd>How much magma the unit produces per simulated second, just by existing.
</dd>
<dt>EnergyStorageCapacity = number</dt>
<dd>How much more energy the player can store by having this unit.
The engine only keeps track of the total amount of stored energy per player,
and not exactly where it has been stored.
</dd>
<dt>MagmaStorageCapacity = number</dt>
<dd>How much more magma the player can store by having this unit.
</dd>
<dt>RightMouseAction = "none" or "move" or "attack" or "harvest"
    or "spell-cast"</dt>
    <dd><dl>
    <dt>"none"</dt>
    <dd>Do nothing.</dd>
    <dt>"move"</dt>
    <dd>Right clicking defaults to move. This should be used for unit's that can't attack.
    </dd>
    <dt>"attack"</dt>
    <dd>Right clicking defaults to attack. This should be used for most combat units.
    </dd>
    <dt>"harvest"</dt>
    <dd>This should be used for resource gathering units. It will return goods when
    on a deposit and mine when on a resource.
    </dd>
    <dt>"spell-cast"</dt>
    <dd>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.
    </dd>
</dl></dd>
<dt id="DefineUnitType.Construction">Construction = construction-name</dt>
<dd>How to draw units of this type while they are being built.
See <a href="game.html#DefineConstruction">DefineConstruction</a>.
</dd>
<dt id="DefineUnitType.ProductionEfficiency">ProductionEfficiency = number</dt>
<dd>Efficiency percentage for energy and magma production
of units built on top of this one, using an
<a href="#DefineUnitType.BuildingRules.ontop">"ontop" building rule</a>.
If the unit type that has a ProductionEfficiency is itself producing
energy (<a href="#DefineUnitType.EnergyProductionRate">EnergyProductionRate</a>)
or magma (<a href="#DefineUnitType.EnergyProductionRate">MagmaProductionRate</a>),
the ProductionEfficiency does not affect those.
</dd>
<dt id="DefineUnitType.CanHarvestFrom">CanHarvestFrom = boolean</dt>
<dd>This is a flag for harvestable resource buildings.
</dd>
<dt id="DefineUnitType.Vanishes">Vanishes = boolean</dt>
<dd>True means the unit is <a href="#DefineUnitType.Corpse">a corpse or a destroyed building</a>.
It cannot be selected, targeted, or killed again;
it just lies there until its animation ends, and then it vanishes.
</dd>
<dt id="DefineUnitType.Building">Building = boolean</dt>
<dd>Unit is a building, and immobile. Available as a spell target check.
</dd>
<dt id="DefineUnitType.Type">Type = "land" or "fly" or "naval"</dt>
<dd>Whether the unit stands/walks/rolls on dry land, flies in the air,
or sails/dives in the water.  This affects several things:
<ul>
  <li>Flying units cannot be blocked by land or naval units, and vice versa.</li>
  <li>Flying units ignore the movement costs defined in map patches.
    They can fly over swamps as fast as over roads.</li>
  <li>By default, land units cannot move in the water,
    and naval units cannot move on the land, but flying units can move anywhere.
    However, you can override these defaults with 
    <a href="#DefineUnitType.AllowTerrainLand">AllowTerrainLand</a>,
    <a href="#DefineUnitType.AllowTerrainCoast">AllowTerrainCoast</a>,
    <a href="#DefineUnitType.AllowTerrainShallowWater">AllowTerrainShallowWater</a>, and
    <a href="#DefineUnitType.AllowTerrainDeepWater">AllowTerrainDeepWater</a>.</li>
  <li>Only land units can board <a href="#DefineUnitType.CanTransport">transporters</a>.
    (FIXME: allow different restrictions for different transporter types.)</li>
  <li>Land units may be unable to attack naval units, or vice versa.
    See <a href="#DefineUnitType.CanTargetLand">CanTargetLand</a>,
    <a href="#DefineUnitType.CanTargetSea">CanTargetSea</a>,
    and <a href="#DefineUnitType.CanTargetAir">CanTargetAir</a>.</li>
  <li>When selecting units with a rectangle, the player can
    press Alt to select only land and naval units,
    or Control to select only flying units.</li>
  <li><a href="magic.html#DefineSpell.action.demolish">The spell action "demolish"</a>
    does not hit flying units.</li>
</ul></dd>
<dt>VisibleUnderFog = boolean</dt>
<dd>Unit remains visible under fog of war. In most games this is true for and only for
<a href="#DefineUnitType.Building">buildings</a>.
</dd>
<dt id="DefineUnitType.ShoreBuilding">ShoreBuilding = boolean</dt>
<dd>Unit is a shore building, and immobile. This is used for those unique buildings
that have to be built on sea and have at least one point on coast.
This restriction is like <a href="#DefineUnitType.BuildingRules">BuildingRules</a> =
{{<a href="#DefineUnitType.BuildingRules.terrain">"terrain"</a>, {CountCoast=true, Min=1}}},
but ShoreBuilding also affects other things:
see <a href="#DefineUnitType.AllowTerrainCoast">AllowTerrainCoast</a>.
</dd>
<dt id="DefineUnitType.AllowTerrainLand">AllowTerrainLand = boolean</dt>
<dd>Explicitly allow or forbid moving the unit to dry land.
By default, only <a href="#DefineUnitType.Type">air units and land units</a> are allowed there.
This also affects whether the unit can be targeted as a land unit
(see <a href="#DefineUnitType.CanTargetLand">CanTargetLand</a>).
</dd>
<dt id="DefineUnitType.AllowTerrainCoast">AllowTerrainCoast = boolean</dt>
<dd>Explicitly allow or forbid moving the unit to coasts.
By default, only air units, naval <a href="#DefineUnitType.CanTransport">transporter</a> units,
and <a href="#DefineUnitType.ShoreBuilding">shore buildings</a> are allowed there.
This does not affect which units can target the unit.
</dd>
<dt id="DefineUnitType.AllowTerrainShallowWater">AllowTerrainShallowWater = boolean</dt>
<dd>Explicitly allow or forbid moving the unit to shallow water.
By default, only air units and naval units are allowed there.
This also affects whether the unit can be targeted as a naval unit
(see <a href="#DefineUnitType.CanTargetSea">CanTargetSea</a>).
</dd>
<dt id="DefineUnitType.AllowTerrainDeepWater">AllowTerrainDeepWater = boolean</dt>
<dd>Explicitly allow or forbid moving the unit to deep water.
By default, only air units and naval units are allowed there.
This also affects whether the unit can be targeted as a naval unit
(see <a href="#DefineUnitType.CanTargetSea">CanTargetSea</a>).
</dd>
<dt id="DefineUnitType.BuildingRules">BuildingRules = { { "distance", { Distance = 3, DistanceType = ">", Type = "unit-gold-mine"}}}
<dd>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.
<dl>
	<dt>"distance"</dt>
	<dd>Specifies a distance constraint.
	<dl>
		<dt>Distance</dt>
		<dd>The distance in tiles to measure</dd>
		<dt>DistanceType</dt>
		<dd>&lt;, &gt;, &lt;=, &gt;=, ==, !=</dd>
		<dt>Type</dt>
		<dd>The type of the unit that this distance restriction applies to</dd>
		<dt>Except <b>NOT IMPLEMENTED</b></dt>
		<dd>boolen, #t implies all units, except this type must be</dd>
	</dl></dd>
	<dt>"addon"</dt>
	<dd>Specifies an addon to an existing building.
	<dl>
	    <dt>OffsetX</dt>
		<dd>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)</dd>
		<dt>OffsetY</dt>
		<dd>As with OffsetX, except in the Y direction</dd>
		<dt>Type</dt>
		<dd>Type of the unit that this unit is an addon too</dd>
	</dl></dd>
	<dt id="DefineUnitType.BuildingRules.ontop">"ontop"</dt>
	<dd>Building must be built on top of another building type.<br>
	    NOTE: the engine may not be able to guess the correct parent if the rules are complex enough.
	    For example, if you define that unit-magmapump can be built
	    on top of either unit-hotspot and unit-weakhotspot,
	    and building the pump removes the hot spot but destroying the pump restores it,
	    then the engine does not remember which type of hot spot it was.
	    This matters especially if the possible underlying unit types have different
	    <a href="#DefineUnitType.ProductionEfficiency">ProductionEfficiency</a> values,
	    but in that case, removing the underlying units during building seems unusual anyway.
	<dl>
	    <dt>Type</dt>
		<dd>The unit-type that we are to build on top of</dd>
		<dt>ReplaceOnDie</dt>
		<dd>boolean, true if you want the original unit to be replaced when this unit dies</dd>
		<dt>ReplaceOnBuild</dt>
		<dd>boolean, true if you want to remove the old unit underneath when you build this one</dd>
	</dl></dd>
	<dt id="DefineUnitType.BuildingRules.terrain">"terrain"</dt>
	<dd>Implement a tile restriction, unit must be placed on certain types of tiles.
	<dl>
		<dt>CountLand = boolean</dt>
		<dt>CountCoast = boolean</dt>
		<dt>CountShallowWater = boolean</dt>
		<dt>CountDeepWater = boolean</dt>
		<dd>Which types of terrain tiles are being counted.</dd>
		<dt>Min = number</dt>
		<dd>Smallest permitted number of such terrain tiles under the unit.
		    If omitted, there is no minimum limit.</dd>
		<dt>Max = number</dt>
		<dd>Greatest permitted number of such terrain tiles under the unit.
		    If omitted, there is no maximum limit.</dd>
	</dl></dd>
	<dt>"direction" <b>NOT IMPLEMENTED</b></dt>
	<dd><dl>
	    <dt>Direction</dt>
		<dd>A bitmask in int format for the directions to build. (bits not specified yet)</dd>
	</dl></dd>
</dl>
<dt>Coward = boolean</dt>
<dd>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.
</dd>
<dt>Harvester = boolean</dt>
<dd>Whether this unit can harvest resources from units that have
<a href="#DefineUnitType.CanHarvestFrom">CanHarvestFrom</a> = true.
</dd>
<dt>Neutral = boolean</dt>
<dd>The unit must always be owned by the neutral player.
The map editor displays the neutral unit types in a separate list.
Neutral unit types for plants and minerals should have
<a href="#DefineUnitType.Building">Building</a> = true so that
the corpses of such units cannot fuel spells; but unlike other buildings,
neutral units can be placed on map fields that do not allow buildings.
</dd>
<dt>CanCastSpell = {spell-name, ...}</dt>
<dd>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"}
</dd>
<dt>AutoCastActive = {spell-name, ...}</dt>
<dd>Lists the spells that the unit casts automatically.
The exact conditions for autocast must be defined under
<a href="magic.html#DefineSpell.autocast">"autocast" in DefineSpell</a>.
The player can switch autocast on and off for individual units
during the game but cannot change the default for new units.
AI players ignore this setting because they have their own
<a href="magic.html#DefineSpell.ai-cast">"ai-cast" section in DefineSpell</a>
and always enable autocast if possible.
</dd>
<dt id="DefineUnitType.RepairRange">RepairRange = number</dt>
<dd>Range that a unit can repair from, eg. RepairRange = 1.
</dd>
<dt>RepairHp = number</dt>
<dd>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.
</dd>
<dt id="DefineUnitType.ComputerReactionRange">ComputerReactionRange = number</dt>
<dd>The reaction range for units of AI players.  Each unit can
automatically attack enemy units that enter its reaction range.
See also <a href="config.html#Preference.ShowReactionRange">Preference.ShowReactionRange</a>.
</dd>
<dt id="DefineUnitType.PersonReactionRange">PersonReactionRange = number</dt>
<dd>The reaction range for units of human players.  Each unit can
automatically attack enemy units that enter its reaction range.
See also <a href="config.html#Preference.ShowReactionRange">Preference.ShowReactionRange</a>.
</dd>
<dt>Priority = number</dt>
<dd>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.
</dd>
<dt>AnnoyComputerFactor = number</dt>
<dd>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.
</dd>
<dt>DecayRate = number</dt>
<dd>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.
</dd>
<dt>BurnPercent = number</dt>
<dd>The unit will start burning when it has less health than this, in percents.
</dd>
<dt>BurnDamageRate = number</dt>
<dd>The rate at which the unit will get damaged. The period is the same
as with <a href="#DefineUnitType.RegenerationRate">regeneration</a>.
</dd>
<dt>Points = number</dt>
<dd>This is the score value of an unit. Used for the final score.
</dd>
<dt>Missile = missile-name</dt>
<dd>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.
</dd>
<dt id="DefineUnitType.Corpse">Corpse = {unittype-name, number}</dt>
<dd>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 unittype-name and a a corpse frame
number. The unit type to which refers should have <a href="#DefineUnitType.Vanishes">Vanishes</a> = true.
As you can see in <a href="#DefineAnimations">DefineAnimations()</a>,
an animation is composed out of several script frames, this is the frame to
start the script from. FE: Corpse = {"unit-dead-body", 0}
</dd>
<dt>ExplodeWhenKilled = missile-name</dt>
<dd>Sets unit to explode when killed, syntax is followed by the missile to use.
eg. ExplodeWhenKilled "missile-explosion"
</dd>
<dt>DeathExplosion = explosion-function</dt>
<dd>Set the lua function that will create the particles of the explosion.
</dd>
<dt>AttackFromTransporter = boolean</dt>
<dd>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
</dd>
<dt id="DefineUnitType.CanTransport">CanTransport = boolean</dt>
<dd>Unit is a transporter, you can place <a href="#DefineUnitType.Organic">organic</a>
<a href="#DefineUnitType.Type">land</a> units inside.
(FIXME: allow different restrictions for different transporter types.)
</dd>
<dt>MaxOnBoard = number</dt>
<dd>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.
</dd>
<dt id="DefineUnitType.Organic">Organic = boolean</dt>
<dd>Only organic units can be carried in <a href="#DefineUnitType.CanTransport">transporters</a>.
<a href="magic.html#DefineSpell.conditions">Spell conditions in DefineSpell</a>
can check the Organic flag, so that you can prevent healing spells
from affecting machines.
</dd>
<dt>Revealer = boolean</dt>
<dd>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.</dd>
<dt>SelectableByRectangle = boolean</dt>
<dd>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.
</dd>
<dt id="DefineUnitType.Mana"><a href="#variable.Mana">Mana</a> = number or boolean or {tag = value, ...}</dt>
<dt><a href="#variable.SightRange">SightRange</a> = number or boolean or {tag = value, ...}</dt>
<dt><a href="#variable.RadarRange">RadarRange</a> = number or boolean or {tag = value, ...}</dt>
<dt><a href="#variable.RadarJammerRange">RadarJammerRange</a> = number or boolean or {tag = value, ...}</dt>
<dt><a href="#variable.Armor">Armor</a> = number or boolean or {tag = value, ...}</dt>
<dt><a href="#variable.BasicDamage">BasicDamage</a> = number or boolean or {tag = value, ...}</dt>
<dt><a href="#variable.PiercingDamage">PiercingDamage</a> = number or boolean or {tag = value, ...}</dt>
<dt id="DefineUnitType.HitPoints"><a href="#variable.HitPoints">HitPoints</a> = number or boolean or {tag = value, ...}</dt>
<dt><a href="#variable.AutoRepairRange">AutoRepairRange</a> = number or boolean or {tag = value, ...}</dt>
<dt><var>custom variable</var> = number or boolean or {tag = value, ...}</dt>
<dd>Each of these tags makes the unit type override some properties
of the identically-named (predefined or custom) variable.
Which properties get overridden depends on the type of the value you provide:
<dl>
  <dt><var>variable</var> = {Value = number, Max = number, Increase = number, Enable = boolean}</dt>
  <dd>Overrides individual properties of the variable.
    The tags and values of the table have the same meanings
    as in <a href="#DefineVariables">DefineVariables</a>.
    If you omit some tags from the table, then the corresponding properties
    set with DefineVariables remain in force.</dd>
  <dt><var>variable</var> = number</dt>
  <dd>Assigns the number as both the initial value and the maximum value
    of the variable, and enables the variable.<br>This is the same as
    <var>variable</var> = {Value = number, Max = number, Enable = true}.</dd>
  <dt><var>variable</var> = boolean</dt>
  <dd>Enables or disables the variable.<br>This is the same as
    <var>variable</var> = {Enable = boolean}.</dd>
</dl>
If you use custom variables, you must define them with
<a href="#DefineVariables">DefineVariables</a> before you define any unit types.
</dd>
<!--IDEA:<dt>force-minimap-color<dt>
<dd>An unit with this flag will ignore any friend/foe/owning player considerations
for the minimap color, and will force this. It takes a number from the palette here.
</dd>-->
</dl>


<h4>Example</h4>
Sorry, but due to the huge number of available flags we can only show a limited example.

<pre class="lua">
DefineUnitType("unit-footman", { Name = "Footman",
  Image = {"file", "alliance/units/footman.png", "size", {72, 72}},
  Animations = "animations-footman", Icon = "icon-footman",
  EnergyValue = 600,
  MagmaValue = 60,
  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,
  Corpse = {"unit-dead-body", 6},
  Type = "land",
  RightMouseAction = "attack",
  CanAttack = true,
  CanTargetLand = true,
  Organic = true,
  SelectableByRectangle = true,
  -- distance is &gt;3 from gold, and &lt;2 from a watch tower
  -- or distance is &gt;6 from goldmine
  BuildingRules = { { "distance", { Distance = 3, DistanceType = "&gt;", Type = "unit-gold-mine"},
  					  "distance", { Distance = 2, DistanceType = "&lt;", Type = "unit-gold-mine"}},
					{ "distance", { Distance = 6, DistanceType = "&gt;", 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"} } )
</pre>

<!--

<LI><var>unit-type</var><br>
    Get the pointer to the unit type structure.<p>
    (unit-type ident)
    <dl>
    <dt>ident</dt>
    <dd>The unit-type unique identifier.</dd>
    </dl>
    <p>
    <h4>Example:</h4>
    (unit-type "unit-peon")<p>
    Get the unit type structure of the peon. #<unittype 0x80ac350 unit-peon><p>

<li><var>unit-type-array</var><br>
    Get an array of all currently defined unit type structures.<p>
    (unit-type-array)
    <p>

<li><var>get-unit-type-ident</var><br>
    Get the unique identfier of the unit type structure.<p>
    (get-unit-type-ident type)
    <dl>
    <dt>type</dt>
    <dd>Unit type pointer</dd>
    </dl>
    <p>
    <h4>Example:</h4>
    (get-unit-type-ident (unit-type "unit-peon"))<p>
    Get the identifier of the unit type peon.<p>
-->

<hr>
All trademarks and copyrights on this page are owned by their respective owners.
<address>(c) 2002-2007 by <a href="http://boswars.org">
The Bos Wars Project</a></address></body></html>