Handy builder script

Handy builder script

Discuss game development here, from a distinct game project to an accessible third-party mutator, down to the interaction and design of individual units if you like.

Moderator: Moderators

Post Reply
User avatar
Peet
Malcontent
Posts: 4384
Joined: 27 Feb 2006, 22:04

Handy builder script

Post by Peet »

This is the product of my toil and epic frustration of the last few hours...figured I may as well share it with everyone. It's a bos fragment that makes a builder unit turn toward the target (definitely easier said than done).

Code: Select all

#define HEADING 82 //add to headers, preferably
#define SIG_BUILD 2
StartBuilding(desired_heading)
{
	set-signal-mask SIG_BUILD;
	if (!isbuilding)
	{
		isbuilding = 1;
		
		var speed;
		speed = <90>; //spin, degrees per second, if it's too big and unit often gets stuck in eternal spins, lower the MSperChange

		// radials = spring angle unit
		var current_heading;
		current_heading = (get HEADING);
		
		var MSperChange;
		MSperChange = 40; // milliseconds per cycle of the loop, smaller values for more cpu usage and smoother anim
		
		var RadialsPerChange; //number of radials to increase by every cycle of the loop, calculated from speed
		RadialsPerChange = (MSperChange * speed) / 1000;

		desired_heading = current_heading + desired_heading; // convert local angle into global one
		if (desired_heading > 65535)
		{
			desired_heading = desired_heading - 65536;
		}
		
		if (desired_heading < get HEADING)
		{
			RadialsPerChange = 0 - RadialsPerChange; // make it go the short way rather than all the way around
		}
		
		var headingdiff; //the difference between desired and current headings
		var PosRadialsPerChange; //absolute value
		
		var doneturning;
		while (!doneturning)
		{
			sleep MSPerChange;
			
			set HEADING to ((get HEADING) + RadialsPerChange); //spin unit
			
			PosRadialsPerChange = RadialsPerChange; //get absolute value
			if (RadialsPerChange < 0)
			{
				PosRadialsPerChange = 0 - RadialsPerChange;
			}
			
			headingdiff = (get HEADING) - desired_heading;
			if (headingdiff < 0)
			{
				headingdiff = headingdiff * -1;
			}
			
			if (headingdiff < PosRadialsPerChange) // prevent overshooting, end loop
			{
				set HEADING to desired_heading;
				doneturning = 1;
			}
		}
		
		set INBUILDSTANCE to 1;
	}
}

StopBuilding()
{
	signal SIG_BUILD;
	isbuilding = 0;
 	set INBUILDSTANCE to 0;
}
As is commented upon in the code, if speed and/or MSperChange are too high your unit will often be unable start building or stop spinning until issued an order to stop building.

I haven't tried this on a unit with weapons....probably would be rather undesirable.

Go ahead and use it, giving me credit (and perhaps a sneak peek of your mod :-)) would be highly preferable of course.except perhaps people who would take it and relicense it, calling it their own work <_< >_>
Last edited by Peet on 21 Jul 2007, 09:02, edited 1 time in total.
User avatar
Pressure Line
Posts: 2283
Joined: 21 May 2007, 02:09

Post by Pressure Line »

you're my hero Peet. im gonna have to make a loading screen for the credits :B
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

That looks so complicated...

Code: Select all

#define TURNRATE <8>

StartBuilding(heading, pitch)
{
	signal SIG_Build;
	set-signal-mask SIG_Build;
	
	while(heading <= 0-TURNRATE) {
		set HEADING to (get HEADING)-TURNRATE;
		heading = heading + TURNRATE;
		sleep 30;
	}

	while(heading >= TURNRATE) {
		set HEADING to (get HEADING)+TURNRATE;
		heading = heading - TURNRATE;
		sleep 30;
	}
	
	set INBUILDSTANCE to TRUE;
}

StopBuilding()
{
	signal SIG_BUILD;
	set INBUILDSTANCE to FALSE;
}
Feel free to modify this, use it in your mod or print it out and use it as toilet paper.

Word of warning: Apparently emit-sfx doesn't realize the unit has been turned, emitting any effects will still happen from the old position of the piece!

Also multiply TURNRATE by 32 to get the actual turnrate per second. Keep in mind that Spring runs at 32 frames per second so the msec value you use is not necessarily the delay that happens.
User avatar
Pressure Line
Posts: 2283
Joined: 21 May 2007, 02:09

Post by Pressure Line »

KDR11k's code as used in my commander model

Code: Select all

#define TURNRATE <1>
#define HEADING	82

TurnUnit(heading)
	{ 
	while(heading <= 0-TURNRATE)
		{
		set HEADING to (get HEADING)-TURNRATE;
		heading = heading + TURNRATE;
		sleep 30;
	}

	while(heading >= TURNRATE) 
	{
		set HEADING to (get HEADING)+TURNRATE;
		heading = heading - TURNRATE;
		sleep 30;
   }
}
	
QueryNanoPiece(piecenum)
	{
	piecenum = nano;
	}

StartBuilding(heading,pitch)
	{
	signal SIG_AIM4;
	set-signal-mask SIG_AIM4;
	if ( heading > -10923 AND heading < 10923 )
	{
		turn nanobase to y-axis heading speed <90.000000>;
		turn nanoturret to x-axis <0.000000> - pitch speed <50.000000>;
		wait-for-turn nanobase around y-axis;
		wait-for-turn nanoturret around x-axis;
	}
	if ( heading > 10923 )
		{
		heading = heading - 5461;
		call-script TurnUnit(heading);
		turn nanobase to y-axis <30.000000> speed <90.000000>;
		turn nanoturret to x-axis <0.000000> - pitch speed <50.000000>;
		wait-for-turn nanobase around y-axis;
		wait-for-turn nanoturret around x-axis;
		}
	if ( heading < -10923 )
		{
		heading = heading + 5461;
		call-script TurnUnit(heading);
		turn nanobase to y-axis <-30.000000> speed <90.000000>;
		turn nanoturret to x-axis <0.000000> - pitch speed <50.000000>;
		wait-for-turn nanobase around y-axis;
		wait-for-turn nanoturret around x-axis;
		}	
	set INBUILDSTANCE to 1;
	}

StopBuilding()
	{
	set INBUILDSTANCE to 0;
	turn nanobase to y-axis <0.000000> speed <90.000000>;
	turn nanoturret to x-axis <0.000000> speed <50.000000>;
	return (1);
	}
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

10923? Isn't it more maintenance-friendly to just denote the angle in <>?
User avatar
Pressure Line
Posts: 2283
Joined: 21 May 2007, 02:09

Post by Pressure Line »

KDR_11k wrote:10923? Isn't it more maintenance-friendly to just denote the angle in <>?
yeah i just couldnt be bothered changing it
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Post by rattle »

Everyone knows that 10923 is ~60°.
Word of warning: Apparently emit-sfx doesn't realize the unit has been turned, emitting any effects will still happen from the old position of the piece!
I'd like to know why, because set HEADING is supposed to actually turn the whole unit.
User avatar
Das Bruce
Posts: 3544
Joined: 23 Nov 2005, 06:16

Re: Handy builder script

Post by Das Bruce »

DasBruce casts ressurect!

I've just remade this script in lua, it was a bit of a bitch trying to figure out the turning behaviour, and I came across what seems like a bloody awkward one.
The script basically just turns the base piece towards the target at an appropriate rate, then turns it back instantly and turns the unit itself instantly to the target direction, but if the constructor didn't move between constructions it would do the turn animation in the wrong direction. I have no idea why, it was trivial to hack around once I figured out that's what it was doing, but why would it do that?

Code: Select all

local body, shovel, nanogun1, nano, nanogun2, nano2, dish = piece ("body", "shovel", "nanogun1", "nano", "nanogun2", "nano2", "dish")

--constants
local SIG_AIM = 2
local SIG_BUILD = 4
local RESTORE_DELAY = 2000
local rad = math.rad
local pi = math.pi

local TURNRATE = 2
local HEADING = 82

--includes
include "rockunit.lua"
include "smokeunit.lua"

function script.Create(unitID)
	turnHack = 1
end

function script.StartBuilding(heading, pitch)
	Signal(SIG_BUILD)
	SetSignalMask(SIG_BUILD)
	originalHeading = GetUnitValue(HEADING)*pi/32768
	
	Turn(body, y_axis, heading*turnHack, TURNRATE)
	Turn(shovel, x_axis, rad(-10), TURNRATE)
	WaitForTurn(body, y_axis)
	
	Turn(body, y_axis, 0)
	Spring.SetUnitRotation(unitID, 0, -(originalHeading+heading), 0 )

	WaitForTurn(shovel, x_axis)
	SetUnitValue(COB.INBUILDSTANCE, 1)
	turnHack = -1
	return 1
end

function script.StopBuilding()
	Signal(SIG_BUILD)
	SetSignalMask(SIG_BUILD)
	SetUnitValue(COB.INBUILDSTANCE, 0)
	Turn(shovel, x_axis, 0, TURNRATE)
	return 0
end

function script.StartMoving()
	turnHack = 1
end
function script.StopMoving()
end

function script.QueryNanoPiece() return nanogun1 end

function script.Killed(recentDamage, maxHealth)
	return 1
end
I know it isn't perfect and will break givin certain situations but it works for now. Just wondering if anybody has info about the odd turn sign behaviour.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Handy builder script

Post by zwzsg »

What's annoying is that StartBuilding only passes the relative angles, and that by using SetHeading, you change the reference to which this relative angle is measured. Would be nice to find a way to get the ID of the built unit, so you could get its position, and from there the absolute angle. With some luck Spring.GetUnitIsBuilding would work, but I'm unsure.

Something like:
x1,_,z1=Spring.GetUnitPosition(unitID)
x2,_,z2=Spring.GetUnitPosition(Spring.GetUnitIsBuilding(unitID))
-- Not sure you can already use GetUnitIsBuilding in script.StartBuilding
Spring.SetUnitRotation(unitID, 0, math.atan2(z2-z1,x2-z1), 0 )
-- Or maybe math.atan2(x2-z1,z2-z1) or maybe math.atan2(x1-z2,z1-z2) or maybe -math.atan2(z1-z2,x1-z2) or ...
-- And with those two zeros, don't you lose the leaning on slopes?
User avatar
Das Bruce
Posts: 3544
Joined: 23 Nov 2005, 06:16

Re: Handy builder script

Post by Das Bruce »

Oh, maybe.

/edit/
Nope, stays at the apropriate angle to ground.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Re: Handy builder script

Post by zwzsg »

Well, I guess that in the absence of MoveCtrl, the unit instantly drop to ground after being set horizontal.
User avatar
Das Bruce
Posts: 3544
Joined: 23 Nov 2005, 06:16

Re: Handy builder script

Post by Das Bruce »

From what I've seen so far, I hold no hope that the reason is as simple or logical as that.
User avatar
Peet
Malcontent
Posts: 4384
Joined: 27 Feb 2006, 22:04

Re: Handy builder script

Post by Peet »

I had forgotten about this...bleh
Post Reply

Return to “Game Development”