Ammunition handling script, derived from Zwzsg's bonus giver script:
Code: Select all
//
// Ammunition refill handler script
// Make sure your unit has a function called RefillAmmo()
//
#include "exptype.h"
#define IS_AMMOREFILLER h == H_MAIN_FACTORY
#define AMMO_REFILL_RADIUS [260]
// Let's assume that all units refill at the same range
// This is where the heights of all refillers would be listed, remember: UNIT_HEIGHT = s3o radius * 65536
#define H_MAIN_FACTORY 3342336 // 51 * 65536
static-var ammunition;
#ifdef MAX_SECONDARY_AMMO
static-var secondary_ammo;
#endif
CheckForRefills()
{
//var selfid;
//selfid = get 71; //MY_ID
while(1) {
sleep 500; //short sleep if ammo is full
var uid;
var cnt;
cnt=0;
#ifndef CUSTOM_CONDITION
#ifndef MAX_SECONDARY_AMMO
if (ammunition < MAX_AMMO) { // don't check if already full
#else
if (ammunition < MAX_AMMO || secondary_ammo < MAX_SECONDARY_AMMO) { // don't check if already full
#endif
#else
if (CUSTOM_CONDITION) {
#endif
for (uid=5000;uid >= 0;--uid) { //thanks, zwzsg
// get 70 = get MAX_ID
// for all units,
if (get 74(uid)) { // UNIT_ALLIED | that are allies,
var h;
h=get UNIT_HEIGHT(uid);
if (IS_AMMOREFILLER) { // and are ammo supplies
if (get XZ_HYPOT(get UNIT_XZ(uid) - get PIECE_XZ(body)) < AMMO_REFILL_RADIUS)
// see, if they are closer than AMMO_REFILL_RADIUS
{
ammunition = MAX_AMMO;
#ifdef MAX_SECONDARY_AMMO
secondary_ammo = MAX_SECONDARY_AMMO;
#endif
start-script RefillAmmo();
uid = -1; //break the loop since ammo is already full
}
}
}
++cnt;
if (cnt>50) {
sleep 30; //do the checks spread out over multiple frames
cnt=0;
}
}
}
}
}
MAX_AMMO must be defined, its use is obvious. If you use two ammo types, define MAX_SECONDARY_AMMO as well, for more than that use CUSTOM_CONDITION. RefillAmmo() must be defined as well and is used to handle e.g. displaying visible ammunition again.
Battle tank script from GINTA, has a main cannon, a shield that represents its armor, a machinegun and a death animation. Note that flare is a null object, it's not visible and as such doesn't get hidden again. It's only there to spawn the smoke pillar. Rewriting the script to use the GPL includes is left as an exercise for the reader ;P.
Code: Select all
piece base, body, turret, cannon, cn, machinegun, mg, ammosymbol, frontarmor;
piece groundsmoke0, groundsmoke1, groundsmoke2, groundsmoke3, groundsmoke4, groundsmoke5;
piece flare, cnsmoke0, cnsmoke1, cnsmoke2, cnsmoke3, cnsmoke4;
#include "SFXtype.h"
#include "exptype.h"
RefillAmmo()
{
hide ammosymbol;
}
#define MAX_AMMO 20
#define MAX_SECONDARY_AMMO 300
#include "ammunition.h"
#define SIG_Move 1
#define SIG_Aim1 2
static-var mainheading;
Create()
{
ammunition = 1;
hide ammosymbol;
spin ammosymbol around y-axis speed <180>;
start-script CheckForRefills();
}
Killed(severity, corpsetype)
{
hide ammosymbol;
explode turret type SHATTER;
explode cannon type FALL | SMOKE;
explode machinegun type FALL | FIRE;
explode frontarmor type FALL | FIRE | SMOKE;
hide turret;
hide cannon;
hide machinegun;
emit-sfx SFXTYPE_BLACKSMOKE from groundsmoke0;
emit-sfx SFXTYPE_BLACKSMOKE from groundsmoke3;
emit-sfx SFXTYPE_BLACKSMOKE from groundsmoke1;
emit-sfx SFXTYPE_BLACKSMOKE from groundsmoke4;
emit-sfx SFXTYPE_BLACKSMOKE from groundsmoke2;
emit-sfx SFXTYPE_BLACKSMOKE from groundsmoke5;
move base to y-axis [-3] speed [1.5];
wait-for-move base along y-axis;
return (3);
}
Sweetspot(piecenum)
{
piecenum=turret;
}
//Cannon
AimWeapon1(h,p)
{
signal SIG_Aim1;
set-signal-mask SIG_Aim1;
if (ammunition > 0)
{
mainheading = h;
turn turret to y-axis h speed <80>;
turn cannon to x-axis 0-p speed <60>;
wait-for-turn turret around y-axis;
wait-for-turn cannon around x-axis;
return TRUE;
}
else
{
show ammosymbol;
return FALSE;
}
}
FireWeapon1()
{
--ammunition;
emit-sfx SFXTYPE_VTOL from cn;
show flare;
emit-sfx SFXTYPE_BLACKSMOKE from cnsmoke4;
emit-sfx SFXTYPE_BLACKSMOKE from groundsmoke2;
emit-sfx SFXTYPE_BLACKSMOKE from groundsmoke5;
sleep 50;
emit-sfx SFXTYPE_VTOL from cnsmoke2;
emit-sfx SFXTYPE_VTOL from cnsmoke0;
sleep 50;
emit-sfx SFXTYPE_VTOL from cnsmoke1;
emit-sfx SFXTYPE_VTOL from cnsmoke3;
}
QueryWeapon1(piecenum)
{
piecenum=cn;
}
AimFromWeapon1(piecenum)
{
piecenum=machinegun;
}
//Armorshield
AimWeapon2(h,p)
{
return TRUE;
}
QueryWeapon2(piecenum)
{
piecenum=frontarmor;
}
//Machinegun
AimWeapon3(h,p)
{
if (secondary_ammo > 0) {
turn machinegun to y-axis (h - mainheading) speed <120>;
turn machinegun to x-axis (0 - p) speed <120>;
wait-for-turn turret around y-axis;
wait-for-turn machinegun around y-axis;
return TRUE;
}
else {
return FALSE;
}
}
AimFromWeapon3(piecenum)
{
piecenum=machinegun;
}
QueryWeapon3(piecenum)
{
piecenum=mg;
}
FireWeapon3(piecenum)
{
--secondary_ammo;
emit-sfx SFXTYPE_VTOL from mg;
}
The gunship, an example for visible ammunition and a custom condition:
Code: Select all
piece base, body, tail, tailrotor, rotorbase, rotor, wing0, wing1, ammosymbol;
piece missilepod0, mp0, missilepod1, mp1, machinegun, mg;
piece atgm0, atgm1, atgm2, atgm3, atgm4, atgm5, atgm6, atgm7;
#include "SFXtype.h"
#include "exptype.h"
#define SIG_Aim1 1
#define SIG_Aim2 2
#define SIG_Aim3 4
#define SIG_Aim4 8
static-var atgmcounter, mpod;
#define CUSTOM_CONDITION ammunition < MAX_AMMO || secondary_ammo < MAX_SECONDARY_AMMO || atgmcounter > 0
RefillAmmo()
{
hide ammosymbol;
atgmcounter=0;
show atgm0;
show atgm1;
show atgm2;
show atgm3;
show atgm4;
show atgm5;
show atgm6;
show atgm7;
show missilepod0;
show missilepod1;
}
#define MAX_AMMO 300
#define MAX_SECONDARY_AMMO 14
#include "ammunition.h"
Create()
{
hide ammosymbol;
spin rotor around y-axis speed <1500>;
spin tailrotor around x-axis speed <800>;
spin ammosymbol around y-axis speed <180>;
ammunition=100;
start-script CheckForRefills();
}
Killed(severity, corpsetype)
{
corpsetype=3;
move body to y-axis [-30] speed [8];
spin body around y-axis speed <90>;
if (atgmcounter < 1) explode atgm0 type FALL | FIRE;
hide atgm0;
if (atgmcounter < 2) explode atgm1 type FALL | FIRE;
hide atgm1;
if (atgmcounter < 3) explode atgm2 type FALL | FIRE;
hide atgm2;
if (atgmcounter < 4) explode atgm3 type FALL | FIRE;
hide atgm3;
if (atgmcounter < 5) explode atgm4 type FALL | FIRE;
hide atgm4;
if (atgmcounter < 6) explode atgm5 type FALL | FIRE;
hide atgm5;
if (atgmcounter < 7) explode atgm6 type FALL | FIRE;
hide atgm6;
if (atgmcounter < 8) explode atgm7 type FALL | FIRE;
hide atgm7;
explode tail type FALL | FIRE | SMOKE;
explode tailrotor type FALL;
hide tail;
hide tailrotor;
sleep 800;
explode rotorbase type FALL | FIRE | SMOKE;
explode rotor type FALL;
explode machinegun type FALL;
hide rotorbase;
hide rotor;
hide machinegun;
sleep 600;
explode wing0 type FALL | FIRE | SMOKE;
explode missilepod0 type FALL | FIRE;
hide wing0;
hide missilepod0;
sleep 300;
explode wing1 type FALL | FIRE | SMOKE;
explode missilepod1 type FALL | FIRE;
hide wing1;
hide missilepod1;
sleep 1200;
explode body type SHATTER;
hide body;
return 3;
}
ResetAim()
{
sleep 8000;
turn body to y-axis 0 speed <180>;
turn machinegun to x-axis 0 speed <240>;
}
//Machinegun
AimWeapon4(h,p)
{
signal SIG_Aim1;
set-signal-mask SIG_Aim1;
if (ammunition>0)
{
wait-for-turn body around x-axis;
wait-for-turn machinegun around y-axis;
return TRUE;
}
else
{
show ammosymbol;
return FALSE;
}
}
AimFromWeapon4(piecenum)
{
piecenum=body;
}
QueryWeapon4(piecenum)
{
piecenum=mg;
}
FireWeapon4()
{
--ammunition;
emit-sfx SFXTYPE_VTOL from mg;
}
//Guided missiles
AimWeapon2(h,p)
{
signal SIG_Aim2;
set-signal-mask SIG_Aim2;
if (atgmcounter<8)
{
wait-for-turn body around x-axis;
return TRUE;
}
else
{
show ammosymbol;
return FALSE;
}
}
AimFromWeapon2(piecenum)
{
piecenum=body;
}
QueryWeapon2(piecenum)
{
if (atgmcounter==0)
{
piecenum = atgm0;
return TRUE;
}
if (atgmcounter==1)
{
piecenum = atgm1;
return TRUE;
}
if (atgmcounter==2)
{
piecenum = atgm2;
return TRUE;
}
if (atgmcounter==3)
{
piecenum = atgm3;
return TRUE;
}
if (atgmcounter==4)
{
piecenum = atgm4;
return TRUE;
}
if (atgmcounter==5)
{
piecenum = atgm5;
return TRUE;
}
if (atgmcounter==6)
{
piecenum = atgm6;
return TRUE;
}
if (atgmcounter==7)
{
piecenum = atgm7;
return TRUE;
}
}
EndBurst2()
{
if (atgmcounter==0)
{
hide atgm0;
}
if (atgmcounter==1)
{
hide atgm1;
}
if (atgmcounter==2)
{
hide atgm2;
}
if (atgmcounter==3)
{
hide atgm3;
}
if (atgmcounter==4)
{
hide atgm4;
}
if (atgmcounter==5)
{
hide atgm5;
}
if (atgmcounter==6)
{
hide atgm6;
}
if (atgmcounter==7)
{
hide atgm7;
}
++atgmcounter;
}
//Unguided missiles
AimWeapon3(h,p)
{
signal SIG_Aim3;
set-signal-mask SIG_Aim3;
if (secondary_ammo>0)
{
wait-for-turn body around x-axis;
return TRUE;
}
else
{
show ammosymbol;
return FALSE;
}
}
AimFromWeapon3(piecenum)
{
piecenum=body;
}
QueryWeapon3(piecenum)
{
if (mpod) {
piecenum=mp0;
}
else
{
piecenum=mp1;
}
}
FireWeapon3()
{
--secondary_ammo;
}
EndBurst3()
{
mpod= 1 - mpod;
}
//Targeting laser
AimFromWeapon1(piecenum)
{
piecenum=body;
}
AimWeapon1(h,p)
{
signal SIG_Aim4;
set-signal-mask SIG_Aim4;
turn body to y-axis h speed <180>;
turn machinegun to x-axis (0 - p) speed <240>;
start-script ResetAim();
return FALSE;
}
QueryWeapon1(piecenum)
{
piecenum=mg;
}
The oil pump, a mex that slowly fills its silo and produces metal for a very short time when that silo is drained by the presence of a refinery or an oil truck (those units aren't implemented yet but their scripts wouldn't need any special behaviour, their mere existence is good enough). It comes with a build and a death animation.
Code: Select all
piece base, tower, towerframe0, towerframe1, towerframe2, towerframe3, exhaust;
piece silo, pipe, oillevel, stream, crate, fuelsymbol, scaffolds;
piece scaffold00, scaffold01, scaffold02, scaffold03;
piece scaffold10, scaffold11, scaffold12, scaffold13;
piece scaffold20, scaffold21, scaffold22, scaffold23;
piece scaffold30, scaffold31, scaffold32, scaffold33;
piece scaffold40, scaffold50, scaffold51, scaffold60, scaffold70, scaffold71;
#include "exptype.h"
#include "sfxtype.h"
#define SIG_StopSmoke 1
#define SIG_Dead 2
#define FULL_CAPACITY 50
#define HALF_CAPACITY 25
static-var oil;
FireTower()
{
set-signal-mask SIG_StopSmoke;
while(1) {
emit-sfx SFXTYPE_BLACKSMOKE from exhaust;
emit-sfx SFXTYPE_BLACKSMOKE from exhaust;
emit-sfx SFXTYPE_VTOL from exhaust;
sleep 100;
}
}
EmptyOil()
{
hide fuelsymbol;
set ACTIVATION to 1;
while(oil > 0) {
move oillevel to y-axis (oil * ([5] / FULL_CAPACITY)) now;
--oil;
sleep 50;
}
set ACTIVATION to 0;
show stream;
start-script FireTower();
}
//*** Begin oil checking code
#define IS_REFINERY h==H_MAIN_FACTORY
#define IS_OILTRUCK FALSE
//Main Factory acts as refinery as well.
#define IS_OILEMPTIER IS_REFINERY || IS_OILTRUCK
#define OILTRUCK_RADIUS [300]
#define REFINERY_RADIUS [900]
// Oiltrucks have less range than refineries
// This is where the heights of all refillers would be listed, remember: UNIT_HEIGHT = s3o radius * 65536
#define H_MAIN_FACTORY 3342336 // 51 * 65536
CheckForEmptier()
{
var uid;
for (uid=0;uid < 5000;++uid) { //thanks, zwzsg
// for all units,
if (get 74(uid)) { // UNIT_ALLIED | that are allies,
var h;
h=get UNIT_HEIGHT(uid);
if (IS_OILEMPTIER) { // and are oil refiners
var dist;
dist=get XZ_HYPOT(get UNIT_XZ(uid) - get PIECE_XZ(base));
// Store distance to compare with Truck and Refinery separately
if (IS_REFINERY && dist < REFINERY_RADIUS)
{
call-script EmptyOil();
}
if (IS_OILTRUCK && dist < OILTRUCK_RADIUS)
{
call-script EmptyOil();
}
}
}
}
}
// *** End oil checking code
//Handles filling the silo and emptying it
DoExtract()
{
start-script EmptyOil();
set-signal-mask SIG_Dead;
while(1)
{
if(oil < FULL_CAPACITY) {
++oil;
move oillevel to y-axis (([5] / FULL_CAPACITY) *oil) speed [1];
}
if (oil >= FULL_CAPACITY) {
signal SIG_StopSmoke;
hide stream;
show fuelsymbol;
//set ACTIVATION to 0;
}
if(oil > HALF_CAPACITY) {
call-script CheckForEmptier();
}
sleep 2000;
}
}
SmokeTower()
{
set-signal-mask SIG_StopSmoke;
while (1) {
emit-sfx SFXTYPE_WHITESMOKE from scaffold00;
emit-sfx SFXTYPE_WHITESMOKE from scaffold01;
sleep 100;
emit-sfx SFXTYPE_WHITESMOKE from scaffold10;
emit-sfx SFXTYPE_WHITESMOKE from scaffold11;
sleep 100;
emit-sfx SFXTYPE_WHITESMOKE from scaffold20;
emit-sfx SFXTYPE_WHITESMOKE from scaffold21;
sleep 100;
emit-sfx SFXTYPE_WHITESMOKE from scaffold30;
emit-sfx SFXTYPE_WHITESMOKE from scaffold31;
sleep 100;
emit-sfx SFXTYPE_WHITESMOKE from tower;
emit-sfx SFXTYPE_WHITESMOKE from exhaust;
sleep 100;
}
}
SmokeSilo()
{
set-signal-mask SIG_StopSmoke;
while (1) {
emit-sfx SFXTYPE_WHITESMOKE from scaffold40;
emit-sfx SFXTYPE_WHITESMOKE from scaffold60;
sleep 100;
emit-sfx SFXTYPE_WHITESMOKE from scaffold50;
emit-sfx SFXTYPE_WHITESMOKE from scaffold51;
sleep 100;
emit-sfx SFXTYPE_WHITESMOKE from scaffold70;
emit-sfx SFXTYPE_WHITESMOKE from scaffold71;
sleep 100;
emit-sfx SFXTYPE_WHITESMOKE from silo;
sleep 100;
}
}
Create()
{
turn base to y-axis <-10> now;
hide fuelsymbol;
hide tower;
hide towerframe0;
hide towerframe1;
hide towerframe2;
hide towerframe3;
hide silo;
hide pipe;
hide oillevel;
hide stream;
hide crate;
// hide scaffold00;
hide scaffold01;
hide scaffold02;
hide scaffold03;
// hide scaffold10;
hide scaffold11;
hide scaffold12;
hide scaffold13;
// hide scaffold20;
hide scaffold21;
hide scaffold22;
hide scaffold23;
// hide scaffold30;
hide scaffold31;
hide scaffold32;
hide scaffold33;
hide scaffold40;
hide scaffold50;
hide scaffold51;
hide scaffold60;
hide scaffold70;
hide scaffold71;
//Build tower scaffold
sleep 300;
show scaffold01;
show scaffold11;
show scaffold21;
show scaffold31;
sleep 300;
show scaffold02;
show scaffold12;
show scaffold22;
show scaffold32;
sleep 300;
show scaffold03;
show scaffold13;
show scaffold23;
show scaffold33;
sleep 300;
// Build tower
move tower to y-axis [-21] now;
show tower;
show towerframe0;
show towerframe1;
show towerframe2;
show towerframe3;
start-script SmokeTower();
while ((get BUILD_PERCENT_LEFT) > 30)
{
move tower to y-axis ([9] - (get BUILD_PERCENT_LEFT) * [0.3]) now;
sleep 100;
}
move tower to y-axis 0 now;
sleep 100; //Workaround in case the building is completed already
signal SIG_StopSmoke;
//Destroy tower scaffold;
turn scaffold00 to x-axis <-90> speed <60>;
turn scaffold10 to z-axis <-90> speed <60>;
turn scaffold20 to x-axis <90> speed <60>;
turn scaffold30 to z-axis <90> speed <60>;
wait-for-turn scaffold00 around x-axis;
hide scaffold00;
hide scaffold01;
hide scaffold02;
hide scaffold03;
hide scaffold10;
hide scaffold11;
hide scaffold12;
hide scaffold13;
hide scaffold20;
hide scaffold21;
hide scaffold22;
hide scaffold23;
hide scaffold30;
hide scaffold31;
hide scaffold32;
hide scaffold33;
//Build silo scaffold
sleep 200;
show scaffold40;
show scaffold60;
sleep 200;
show scaffold50;
show scaffold70;
sleep 200;
show scaffold51;
show scaffold71;
//build Silo
start-script SmokeSilo();
show silo;
move silo to y-axis [-6] now;
while ((get BUILD_PERCENT_LEFT)>0)
{
move silo to y-axis (get BUILD_PERCENT_LEFT) * [-.3] now;
sleep 100;
}
move silo to y-axis 0 now;
sleep 100; //Workaround to make sure the smoke stops even when the building is cheated.
signal SIG_StopSmoke;
//destroy Silo scaffold
hide scaffold51;
hide scaffold71;
sleep 200;
hide scaffold50;
hide scaffold70;
sleep 200;
hide scaffold40;
hide scaffold60;
sleep 200;
show pipe;
show oillevel;
show crate;
oil=10;
start-script DoExtract();
}
Killed(severity, corpsetype)
{
signal SIG_Dead;
signal SIG_StopSmoke;
start-script SmokeTower();
start-script SmokeSilo();
set ACTIVATION to 0; //since that is apparently not automatic
explode crate type FALL | FIRE;
explode pipe type SHATTER;
hide pipe;
hide crate;
hide stream;
hide oillevel;
turn towerframe0 to z-axis <90> speed <30>;
turn towerframe1 to x-axis <90> speed <30>;
turn towerframe2 to z-axis <-90> speed <30>;
turn towerframe3 to x-axis <-90> speed <30>;
move tower to y-axis [-25] speed [5];
spin tower around z-axis speed <10>;
sleep 700;
explode towerframe1 type SHATTER;
hide towerframe1;
move silo to y-axis [-15] speed [8];
spin silo around z-axis speed <15>;
sleep 300;
explode towerframe2 type SHATTER;
hide towerframe2;
sleep 1200;
explode towerframe0 type SHATTER;
hide towerframe0;
sleep 900;
explode towerframe3 type SHATTER;
hide towerframe3;
wait-for-move silo along y-axis;
signal SIG_StopSmoke;
wait-for-move tower along y-axis;
return 3;
}
The ammo script is probably the only one that will be of any use to others but meh.