Page 1 of 4

GPL Code Repository

Posted: 07 Oct 2006, 21:14
by Argh
Image
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.

Posted: 07 Oct 2006, 21:17
by Argh
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: Select all

// 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_

Posted: 07 Oct 2006, 21:21
by Argh
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: Select all

// 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_

Posted: 07 Oct 2006, 21:27
by Argh
The Lord script. I cut out a lot've fat with this one. Very specific to Commander-type applications.

Code: Select all

// 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"

piece base, upperbody, lowerbody, neck, head;
piece fxsphereone, fxspheretwo, fxspherethree, fxspherefour, fxspherefive, fxspheresix, fxsphereseven, fxsphereeight, fxspherenine;
piece rshoulder, rforearm, rhand, flare, shootpoint;
piece lshoulder, lforearm, lhand, nanocenter, nano1, nano2, nano3, nano4;
piece nano_symbol;

// 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"

static-var  BuildHeading, IsBuilding, NanoNumber;
#define	SIG_AIM		1
#define SIG_RESTORE		2
#define SIG_ACTIVATE	4

BuildScript_Mobile()
{
	while(TRUE)
	{
		if(IsBuilding)
		{
			set INBUILDSTANCE to 1;
			turn upperbody to y-axis BuildHeading speed <300>;
			turn lshoulder to y-axis <-60> speed <200>;
			turn lshoulder to z-axis <-20> speed <200>;
			turn lforearm to y-axis <-15> speed <200>;
			turn lhand to z-axis <-10> speed <200>;
			wait-for-turn upperbody around y-axis;
		}
		while(!IsBuilding)
		{
			sleep 1000;
			set INBUILDSTANCE to 0;
			turn upperbody to y-axis <0> speed <300>;
			turn lshoulder to y-axis <0> speed <200>;
			turn lshoulder to z-axis <75> speed <200>;
			turn lforearm to y-axis <-10> speed <200>;
			turn lhand to z-axis <0> speed <200>;
		}
	}
}


StartBuilding(heading)
{
	IsBuilding = TRUE;
	BuildHeading = heading;
}

StopBuilding()
{
	IsBuilding = FALSE;
}

// 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>;
}

QueryNanoPiece(piecenum)
{
	if( NanoNumber == 1 )
	{
		piecenum = nano1;
	}
	if( NanoNumber == 2 )
	{
		piecenum = nano2;
	}
	if( NanoNumber == 3 )
	{
		piecenum = nano3;
	}
	if( NanoNumber == 4 )
	{
		piecenum = nano4;
	}
	++NanoNumber;
	if( NanoNumber == 5 )
	{
		NanoNumber = 1;
	}
	return (0);
}

SweetSpot (piecenum)
{
	piecenum = base;
}


RestoreAfterDelay()
{
 	sleep 1000;
	turn upperbody to y-axis <0> speed <300>;
	turn rshoulder to y-axis <0> speed <200>;
	turn rshoulder to z-axis <-75> speed <200>;
	turn rforearm to y-axis <10> speed <100>;
	turn rhand to z-axis <0> speed <100>;
 	sleep 200;
 	hide flare;
	return (0);
}

AimPrimary(heading, pitch)
{
	signal SIG_AIM;
	set-signal-mask SIG_AIM;
	show flare;
	turn upperbody to y-axis heading speed <300>;
	turn rshoulder to y-axis <45> speed <200>;
	turn rshoulder to z-axis <-10> speed <200>;
	turn rforearm to y-axis <45> speed <200>;
	turn rhand to z-axis <10> speed <200>;
	wait-for-turn rforearm around y-axis;
	turn shootpoint to x-axis 0 - pitch now;
	wait-for-turn upperbody around y-axis;
	start-script RestoreAfterDelay();
	return(TRUE);
}

AimFromPrimary (piecenum)
{
	piecenum = upperbody;
}

QueryPrimary(piecenum)
{
	piecenum = shootpoint;
	return 0;
}
	
FirePrimary()
{
	return 0;
}

Killed(severity, corpsetype)
{
hide fxsphereone;
hide fxspheretwo;
hide fxspherethree; 
hide fxspherefour;
hide fxspherefive;
hide fxspheresix;
hide fxsphereseven;
hide fxsphereeight;
hide fxspherenine;
		explode upperbody type SHATTER | SMOKE | FIRE | BITMAP_GPL;
		explode lowerbody type SHATTER | SMOKE | FIRE | BITMAP_GPL;
		explode rshoulder type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP_GPL;
		explode lshoulder type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP_GPL;
		explode lforearm type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP_GPL;
		explode rforearm type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP_GPL;
		explode lhand type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP_GPL;
		explode rhand type FALL | SMOKE | EXPLODE_ON_HIT | BITMAP_GPL;
	return (0);
}

Posted: 07 Oct 2006, 21:29
by Argh
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: Select all

// 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);
}

QueryNanoPiece(piecenum)
{
	piecenum = nanopoint;
	return (0);
}

Activate()
{
	signal SIG_ACTIVATE;
	IsBuilding = TRUE;
}

Deactivate()
{
	signal SIG_ACTIVATE;
	set-signal-mask SIG_ACTIVATE;
	IsBuilding = FALSE;
	set-signal-mask 0;	
}

QueryBuildInfo(piecenum)
{
	piecenum = base;
	return (0);
}

SweetSpot(piecenum)
{
	piecenum = base;
	return (0);
}

Killed(severity, corpsetype)
{
	sleep 200;
	play-sound("Argh_MedExplosion",20);
	explode body type FALL | SMOKE | FIRE | EXPLODE_ON_HIT | BITMAP_GPL;
	return (0);
}

Posted: 07 Oct 2006, 21:31
by Argh
The Sheep. Again, minimal code pure builders.

Code: Select all

// Argh's GPL Sheep 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, turret, sprayer, nanospray, frlegs, bklegs;
piece nano_symbol;

// 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>;
		}
	}
}

StartBuilding(heading)
{
	BuildHeading = heading;
	IsBuilding = TRUE;
}

StopBuilding()
{
	IsBuilding = FALSE;
}

QueryNanoPiece(piecenum)
{
	piecenum = nanospray;
}

Movement()	
{
	while(1)
	{	
		// starts moving
  		if(IsMoving)
 		{
 			wait-for-turn frlegs around x-axis;
			turn frlegs to x-axis <30> speed <100>;
			turn bklegs to x-axis <30> speed <100>;
		}
		while(!IsMoving)
		// stop motion
		{
			sleep 100;
			wait-for-turn frlegs around x-axis;
			turn frlegs to x-axis <0> speed <100>;
			turn bklegs to x-axis <0> speed <100>;
		}
	}
}

SweetSpot (piecenum)
	{
	piecenum = base;
	}

Create()
{
	hide base;
	start-script SmokeUnit_GPL();
	IsBuilding = FALSE;
	IsMoving = FALSE;
	start-script BuildScript_Mobile();
	start-script Movement();
}

StartMoving()
{
 	IsMoving = TRUE;
}

StopMoving()
{
	IsMoving = FALSE;
}


Killed(severity, corpsetype)
{
	return (0);
}

Posted: 07 Oct 2006, 21:45
by Argh
Here's another useful thing: a script that properly handles aiming behaviors for units in Spring using limited fire-arcs, without any borking.

Code: Select all

//Define this at the top of the script

static-var heading_01, pitch_01;
#define	SIG_AIM1	2

// This part assumes that your Pieces are Gun and Turret.  Change the names to "whatever" and you're done, for a simple two-rotating-part weapon.

AimPrimary(heading, pitch)
{
	signal SIG_AIM1;
	set-signal-mask SIG_AIM1;
 	pitch_01 = pitch;
 	if ( pitch_01 <= 32768 )
 	{
 		turn gun to x-axis 0 - pitch speed <160.0>;
 	}
 	if ( pitch_01 > 32768 )
 	{
 		turn gun to x-axis pitch speed <160.0>;
 	}
 	heading_01 = heading;
 	if ( heading_01 <= 32768 )
 	{
 		turn turret to y-axis heading speed <160.0>;
 	}
 	if ( heading_01 > 32768 )
 	{
 		turn turret to y-axis 0 - heading speed <160.0>;
 	}
	wait-for-turn turret around y-axis;
	wait-for-turn gun around x-axis;
	start-script RestoreAfterDelay();
	return(TRUE);
}

Posted: 07 Oct 2006, 22:08
by KDR_11k
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.

Posted: 12 Oct 2006, 05:24
by Argh
<bumps>

I will post up s'more example code from NanoBlobs soonish- animation code, with commentary. I'm working on the new units tonight tho.

I hope zszwg is nice enough to re-post some stuff here, too- most of my work was more-or-less based on what he'd already figured out.

Oh yeah, and I also put this into the Wiki.

Posted: 12 Oct 2006, 08:18
by SpikedHelmet
Hi. Come work for us. Thx.

Posted: 12 Oct 2006, 08:31
by Forboding Angel
Wow, argh, you are nothing short of simply amazing.

Posted: 12 Oct 2006, 08:38
by Argh
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.

Posted: 12 Oct 2006, 08:43
by SpikedHelmet
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).

And I can pay you... with LOVE!

Posted: 12 Oct 2006, 09:01
by Forboding Angel
SpikedHelmet wrote:...
And I can pay you... with LOVE!
ewww...

Posted: 12 Oct 2006, 09:04
by Argh
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.

Code: Select all

#include "STANDARD_COMMANDS_GPL.h"

static-var Experience;

VeteranLevelLoop()
{
	While(TRUE)
	{
		Experience = GET VETERAN_LEVEL;
		sleep 1000;
	}
}

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);
	}
}

Create()
{
	start-script VeteranLevelLoop();
	//other stuff
}

Posted: 12 Oct 2006, 09:40
by KDR_11k
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.

Posted: 12 Oct 2006, 09:53
by SpikedHelmet
I have no idea what you just said, but I tried that scripting bit you gave, Argh, and it didn't work. Simply kept using its regular weapon...

More specifically: it didn't seem to register that Experience was above 10 at all (I made it 10 instead of 1000).

Posted: 12 Oct 2006, 10:56
by Argh
Hmm.

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.

Posted: 12 Oct 2006, 14:59
by pheldens
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.

Posted: 12 Oct 2006, 15:18
by KDR_11k
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.