Since the private Modder's Forum never seems to get around to getting created around here I'm starting a thread to distribute GPL code for all modders to use.
If you are willing to post your source under the GPL (read the license if you're not sure what that means), feel that your sourcecode could benefit all game designers working with Spring, and are willing to take the time to comment it so that people can make use of it, please post it here.
Last edited by Argh on 07 Oct 2006, 20:35, edited 1 time in total.
This is a simple header file, included with NanoBlobs, which contains all of the known working commands that can be invoked. Generally speaking, if you're making a Spring mod at this time, you want to use TA:K compiling options, btw.
Code:
// Argh's Standard Commands Script // This script is released under the terms of the GNU license. // It may be used by anyone, for any purpose, so long as you adhere to the GNU license. #ifndef STANDARD_COMMANDS_GPL_H_ #define STANDARD_COMMANDS_GPL_H_ // // Vector-based special effects // #define SFXTYPE_VTOL 1 #define SFXTYPE_THRUST 2 #define SFXTYPE_WAKE1 3 #define SFXTYPE_WAKE2 4 #define SFXTYPE_REVERSEWAKE1 5 #define SFXTYPE_REVERSEWAKE2 6 // // Point-based (piece origin) special effects // #define SFXTYPE_POINTBASED 256 #define SFXTYPE_WHITESMOKE (SFXTYPE_POINTBASED | 1) #define SFXTYPE_BLACKSMOKE (SFXTYPE_POINTBASED | 2) #define SFXTYPE_SUBBUBBLES 256 | 3 // #define SHATTER 1 // The piece will shatter instead of remaining whole #define EXPLODE_ON_HIT 2 // The piece will explode when it hits the ground #define FALL 4 // The piece will fall due to gravity instead of just flying off #define SMOKE 8 // A smoke trail will follow the piece through the air #define FIRE 16 // A fire trail will follow the piece through the air #define BITMAPONLY 32 // The piece will just show the default explosion bitmap. // // Bitmap Explosion Types // #define BITMAP_GPL 10000001 // // Indices for set/get value #define ACTIVATION 1 // set or get #define STANDINGMOVEORDERS 2 // set or get #define STANDINGFIREORDERS 3 // set or get #define HEALTH 4 // get (0-100%) #define INBUILDSTANCE 5 // set or get #define BUSY 6 // set or get (used by misc. special case missions like transport ships) #define PIECE_XZ 7 // get #define PIECE_Y 8 // get #define UNIT_XZ 9 // get #define UNIT_Y 10 // get #define UNIT_HEIGHT 11 // get #define XZ_ATAN 12 // get atan of packed x,z coords #define XZ_HYPOT 13 // get hypot of packed x,z coords #define ATAN 14 // get ordinary two-parameter atan #define HYPOT 15 // get ordinary two-parameter hypot #define GROUND_HEIGHT 16 // get #define BUILD_PERCENT_LEFT 17 // get 0 = unit is built and ready, 1-100 = How much is left to build #define YARD_OPEN 18 // set or get (change which plots we occupy when building opens and closes) #define BUGGER_OFF 19 // set or get (ask other units to clear the area) #define ARMORED 20 // SET or GET. Turns on the Armored state. #define IN_WATER 28 // GET only. If unit position Y less than 0, then the unit must be in water (0 Y is the water level). #define CURRENT_SPEED 29 // SET only, if I'm reading the code right. Gives us a new speed for the next frame ONLY. #define VETERAN_LEVEL 32 // SET or GET. Can make units super-accurate, or keep them inaccurate. #define MAX_ID 70 // GET only. Returns maximum number of units - 1 #define MY_ID 71 // GET only. Returns ID of current unit #define UNIT_TEAM 72 // GET only. Returns team of unit given with parameter #define UNIT_BUILD_PERCENT_LEFT 73 // GET only. BUILD_PERCENT_LEFT, but comes with a unit parameter. #define UNIT_ALLIED 74 // GET only. Is this unit allied to the unit of the current COB script? 1=allied, 0=not allied #define MAX_SPEED 75 // SET only. Alters MaxVelocity for the given unit. // #endif // STANDARD_COMMANDS_GPL_H_
A replacement for good ol' SmokeUnit.h. The minute I saw the way that it was originally done, I nearly up-chucked- the old code is veeeeery ugly. This is much shorter. Oh, and btw... if you changed out the emit-sfx commands to use 1024+1, +2, etc., you could easily make this sucker a standardized template for invoking generic "smoke/fire/sparks" customExplosionGenerators Just a thought...
Code:
// Argh's GPL Smoke Script // This script is released under the terms of the GNU license // And may be used by anyone, for any purpose, so long as you adhere to the GNU license.
#ifndef SMOKEUNIT_GPL_H_ #define SMOKEUNIT_GPL_H_
// Very, very, VERY IMPORTANT!!! // You must define SMOKEPIECE1 through SMOKEPIECE4... // I don't care, and neither does Spring, if you define them all as "base", but you MUST DEFINE THEM. // For the ultra-newbie, here's an example: // #define SMOKEPIECE1 base // #define SMOKEPIECE2 body // #define SMOKEPIECE3 foot // #define SMOKEPIECE4 someotherthing.
SmokeUnit_GPL() { while(TRUE) { // First, we sleep. No point in checking this all the time, right? 20 times a second is good enough. sleep 50; // We do not want our units to smoke when they're not done building, do we? This part prevents that. while( get BUILD_PERCENT_LEFT ) { sleep 400; } // // Now we want to emit smoke from a random SMOKEPIECE. // The following variables are used to determine which SMOKEPIECE gets used (RollTheDice) // What level of Health to emit Smoke (HealthLevel) // What the named effect is that we're calling (SmokePuff) // ...and a number we're assigning a random value to keep things interesting (SmokeNumber). // You could vary things even more, but this will produce pretty interesting smoke, and it's cheap on lines of code. // // var RollTheDice, HealthLevel, SmokePuff, SmokeNumber; // // // Now we get HealthLevel, which is just the current value of HEALTH. HealthLevel = get HEALTH; if(HealthLevel < 66) { SmokePuff = SFXTYPE_WHITESMOKE; SmokeNumber = Rand(0,2); If (SmokeNumber <= 1){SmokePuff = SFXTYPE_BLACKSMOKE;} If (SmokeNumber > 1){SmokePuff = SFXTYPE_WHITESMOKE;} if(HealthLevel < 66 || HealthLevel >= 45) { sleep 300; } if(HealthLevel < 45 || HealthLevel >= 15) { sleep 200; } if(HealthLevel < 15 || HealthLevel >= 0) { sleep 100; } RollTheDice = Rand(0,10); if(RollTheDice > 0 || RollTheDice <= 1) { emit-sfx SmokePuff from SMOKEPIECE1; } if(RollTheDice > 1 || RollTheDice <= 2) { emit-sfx SmokePuff from SMOKEPIECE2; } if(RollTheDice > 2 || RollTheDice <= 3) { emit-sfx SmokePuff from SMOKEPIECE3; } if(RollTheDice > 3 || RollTheDice <= 4) { emit-sfx SmokePuff from SMOKEPIECE4; } } } } #endif // if SMOKEUNIT_GPL_H_
The Lord script. I cut out a lot've fat with this one. Very specific to Commander-type applications.
Code:
// Argh's GPL Lord Script
// This script is released under the terms of the GNU license. // All contents were created by Wolfe Games. // You may use these scripts as the basis of your mod, so long as you adhere to the terms of the GPL. // Credit would be nice, too.
// This Include is absolutely VITAL. // You must call it FIRST. PERIOD. // Don't say I didn't warn you ;-) #include "STANDARD_COMMANDS_GPL.h"
// SmokeUnit_GPL is a completely optional Include. It *requires* STANDARD_COMMANDS_GPL.h // ...to be included (or the code) *BEFORE* you call it. // And SMOKEPIECE1 through SMOKEPIECE4 MUST BE DEFINED! // It doesn't matter if they all refer to the same part. #define SMOKEPIECE1 upperbody #define SMOKEPIECE2 lowerbody #define SMOKEPIECE3 head #define SMOKEPIECE4 upperbody #include "SmokeUnit_GPL.h"
// This section is just the visual effect of the green particles that fly "into" the Lord. // You can safely remove this entire Function. NanoBlobs() { while (TRUE) { show fxsphereone; move fxsphereone to y-axis [22.5] speed [7.5]; move fxsphereone to x-axis [1] speed [0.25]; move fxsphereone to z-axis [1] speed [0.25]; hide fxspheresix; move fxspheresix to y-axis [0] now; move fxspheresix to x-axis [0] now; move fxspheresix to z-axis [0] now; sleep 250;
show fxspheretwo; move fxspheretwo to y-axis [22.5] speed [7.5]; move fxspheretwo to x-axis [1] speed [0.25]; move fxspheretwo to z-axis [1] speed [0.25]; hide fxsphereseven; move fxsphereseven to y-axis [0] now; move fxsphereseven to x-axis [0] now; move fxsphereseven to z-axis [0] now; sleep 250;
show fxspherethree; move fxspherethree to y-axis [22.5] speed [7.5]; move fxspherethree to x-axis [-1] speed [0.25]; move fxspherethree to z-axis [-0.5] speed [0.25]; hide fxsphereeight; move fxsphereeight to y-axis [0] now; move fxsphereeight to x-axis [0] now; move fxsphereeight to z-axis [0] now; sleep 250;
show fxspherefour; move fxspherefour to y-axis [22.5] speed [7.5]; move fxspherefour to x-axis [1] speed [0.25]; move fxspherefour to z-axis [-1] speed [0.25]; hide fxspherenine; move fxspherenine to y-axis [0] now; move fxspherenine to x-axis [0] now; move fxspherenine to z-axis [0] now; sleep 250;
show fxspherefive; move fxspherefive to y-axis [22.5] speed [7.5]; move fxspherefive to x-axis [0.5] speed [0.25]; move fxspherefive to z-axis [0.5] speed [0.25]; hide fxsphereone; move fxsphereone to y-axis [0] now; move fxsphereone to x-axis [0] now; move fxsphereone to z-axis [0] now; sleep 250;
show fxspheresix; move fxspheresix to y-axis [22.5] speed [7.5]; move fxspheresix to x-axis [-0.5] speed [0.25]; move fxspheresix to z-axis [-0.5] speed [0.25]; hide fxspheretwo; move fxspheretwo to y-axis [0] now; move fxspheretwo to x-axis [0] now; move fxspheretwo to z-axis [0] now; sleep 250;
show fxsphereseven; move fxsphereseven to y-axis [22.5] speed [7.5]; move fxsphereseven to x-axis [1] speed [0.25]; move fxsphereseven to z-axis [-1] speed [0.25]; hide fxspherethree; move fxspherethree to y-axis [0] now; move fxspherethree to x-axis [0] now; move fxspherethree to z-axis [0] now; sleep 250;
show fxsphereeight; move fxsphereeight to y-axis [22.5] speed [7.5]; move fxsphereeight to x-axis [-1] speed [0.25]; move fxsphereeight to z-axis [1] speed [0.25]; hide fxspherefour; move fxspherefour to y-axis [0] now; move fxspherefour to x-axis [0] now; move fxspherefour to z-axis [0] now; sleep 250;
show fxspherenine; move fxspherenine to y-axis [22.5] speed [7.5]; move fxspherenine to x-axis [0.5] speed [0.25]; move fxspherenine to z-axis [-0.5] speed [0.25]; hide fxspherefive; move fxspherefive to y-axis [0] now; move fxspherefive to x-axis [0] now; move fxspherefive to z-axis [0] now; sleep 250; } return 0; }
Create() { IsBuilding = FALSE; BuildHeading = <0>; turn rshoulder to y-axis <0> now; turn rshoulder to z-axis <-45> now; turn rshoulder to z-axis <-75> now; turn rforearm to y-axis <10> now; turn rhand to z-axis <0> now; turn lshoulder to y-axis <0> now; turn lshoulder to z-axis <-45> now; turn lshoulder to z-axis <75> now; turn lforearm to y-axis <-10> now; turn lhand to z-axis <0> now; hide base; start-script BuildScript_Mobile(); start-script SmokeUnit_GPL(); start-script NanoBlobs(); hide flare; spin flare around x-axis speed <150>; spin nanocenter around y-axis speed <600>; }
The AutoFac script. Can you code a factory with moving parts and significantly fewer lines, without any engine bugs? Please let me know- I think this is about as clean as it gets now.
Code:
// Argh's GPL AutoFac Script
// This script is released under the terms of the GNU license. // All contents were created by Wolfe Games. // You may use these scripts as the basis of your mod, so long as you adhere to the terms of the GPL. // Credit would be nice, too.
// This Include is absolutely VITAL. // You must call it FIRST. PERIOD. // Don't say I didn't warn you ;-) #include "STANDARD_COMMANDS_GPL.h"
piece base, body, nanopoint;
// SmokeUnit_GPL is a completely optional Include. It *requires* STANDARD_COMMANDS_GPL.h // ...to be included (or the code) *BEFORE* you call it. // And SMOKEPIECE1 through SMOKEPIECE4 MUST BE DEFINED! // It doesn't matter if they all refer to the same part. #define SMOKEPIECE1 body #define SMOKEPIECE2 body #define SMOKEPIECE3 body #define SMOKEPIECE4 body #include "SmokeUnit_GPL.h"
static-var IsBuilding; #define SIG_ACTIVATE 2
BuildScript() { while(TRUE) { if(IsBuilding) { wait-for-move body along y-axis; move body to y-axis [50] speed [5]; spin body around y-axis speed <25> accelerate <5>; wait-for-move body along y-axis; set BUGGER_OFF to 1; set YARD_OPEN to 1; set INBUILDSTANCE to 1; } if(IsBuilding) { wait-for-move body along y-axis; move body to y-axis [40] speed [10]; } while(!IsBuilding) { sleep 100; wait-for-move body along y-axis; move body to y-axis [10] speed [25]; spin body around y-axis speed <5> accelerate <1>; set BUGGER_OFF to 0; set YARD_OPEN to 0; set INBUILDSTANCE to 0; } } }
Create() { hide base; set BUGGER_OFF to 0; set YARD_OPEN to 0; set INBUILDSTANCE to 0; IsBuilding = FALSE; start-script BuildScript(); start-script SmokeUnit_GPL(); return (0); }
// This script is released under the terms of the GNU license. // All contents were created by Wolfe Games. // You may use these scripts as the basis of your mod, so long as you adhere to the terms of the GPL. // Credit would be nice, too.
// This Include is absolutely VITAL. // You must call it FIRST. PERIOD. // Don't say I didn't warn you ;-) #include "STANDARD_COMMANDS_GPL.h"
// SmokeUnit_GPL is a completely optional Include. It *requires* STANDARD_COMMANDS_GPL.h // ...to be included (or the code) *BEFORE* you call it. // And SMOKEPIECE1 through SMOKEPIECE4 MUST BE DEFINED! // It doesn't matter if they all refer to the same part. #define SMOKEPIECE1 body #define SMOKEPIECE2 body #define SMOKEPIECE3 body #define SMOKEPIECE4 body #include "SmokeUnit_GPL.h"
static-var BuildHeading, IsBuilding, IsMoving;
BuildScript_Mobile() { while(TRUE) { if(IsBuilding) { turn turret to y-axis BuildHeading speed <400>; wait-for-turn turret around y-axis; set INBUILDSTANCE to 1; } while(!IsBuilding) { sleep 100; set INBUILDSTANCE to 0; turn turret to y-axis <0> speed <5>; } } }
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.
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:
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; }
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; } }
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.
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;
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>;
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;
Whatchu paying And can I make mechs that transform into tanks, and vice-versa? And make bee-guns, for extra-extra-experienced dudes to be equipped with when they've killed enough random bad guys?
On a less-annoying note... after looking at your alpha's COBs a bit, I saw your soldiers are still using move/turn NOW stuff. You guys would see a really huge change in overall efficiency if your walk-cycles were all thoroughly "zszwg'd" and used turn/move <SPEED>*SIM_SPEED stuff. My only real embarrassment in NanoBlobs is that I couldn't get it to work with something as complex as the Springer- the animations just never quite lined up over time and I had to resort to Spring's interpolator. However, for a human walk-cycle, it should be trivial.
And... er, I'm not amazing. I pretty much extended the ideas that zszwg was kind enough to talk to me about and applied them to several cases, is all- I really can't take credit for much here, honestly, other than knowing a good idea when I saw one. I am sure that he may even have some ways to improve them, although I think that the factory/builder/Commander stuff is about as clean as it can be.
Unfortunately my scripting skills aren't all that great. I felt using <now> was simply the most expedient way to get it done -- also, I felt that using speed sometimes made for strange looking things happening.
And I can't promise mech-tanks or bee-guns but we do have lots of things we could use help with! For instance, yes, the experience-weapon-upgrade-thingamajigger as well as a lot of custom explosion stuff (ie, tanks exploding cool-ly when they die, infantry having limbs torn in showers of blood, massive explosions creating shockwave effects, etc).
Great. I ask for payment, and get an offer of man-love from a somewhat-prickly dude whose handle is painful
Seriously speaking... I intend to deliver on a promise, made to several folks, to teach a bit more about explosiongenerator-fu. As for the weapon-upgrade thingy... this should do it, I'd think. Zszwg has made several cryptic posts referring to Spring handling aiming-interruption code poorly, so there may be more to it than this, but I doubt it.
AimPrimary() { If(Experience < 0.500000) { //Do aiming-code here return(TRUE); }Else{ //Hide the gun, and turn it to an angle where it is NEVER going to satisfy Tolerance! return(FALSE); } }
AimSecondary() { If(Experience >= 0.500000) { //Do aiming-code here return(TRUE); }Else{ //Hide the gun, and turn it to an angle where it is NEVER going to satisfy Tolerance! return(FALSE); } }
Return false is enough, no need to sleep forever, especially since the function would get called VERY often (every time the unit wants to know "well, is it ready NOW?") and you'd end up with thousands of instances of it all running at the same time. At least use a signal to make sure only one instance of it runs at the same time.
Also if you check the experience only on specific trigger conditions why do you need a loop to write it into a variable? If you used get VETERAN_LEVEL in the condition you'd always get the up-to-date number instead of the state at the last update and you'd avoid having a loop run all the time.
First off, I dunno if set-signal-mask would work right. Lemme think that one over.
Secondly, I thought the loop would prevent it from having to do a big memory-search over and over again (Spring calls the aiming code for units at least every five frames or so, if not more often, to check and see if a unit can fire now). I figured that was faster to have the loop, in the large scale, than hundreds of deep memory searches every few frames, but the bigger issue is why didn't it work for Spiked, period?
As for Experience... er, didja test it by having the unit shoot a valid enemy? Because that's how VETERAN_LEVEL gets set. Hmm... waitaminute... VETERAN_LEVEL is a very small number... try the above (modified) code instead.
Does it mean that if you include these in your mod, your mod becomes GPL too, else you're in violation of the GPL and cant use the code? I think that was true for headers.
I'm not sure if it's really faster to access a script-defined static variable than a unit property. The unit property is part of the class definition and I think as such easier to find than a variable that was dynamically assigned.
Either way we're talking about a few cycles maximum, I think simply interpreting the COB script takes more time than that.
Users browsing this forum: No registered users and 1 guest
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum