GPL DISCUSSION - Page 3

GPL DISCUSSION

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

User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Post by rattle »

Are you trying to compete with Zoombie?
User avatar
TheRegisteredOne
Posts: 398
Joined: 10 Dec 2005, 21:39

Post by TheRegisteredOne »

However, when I got here, I very quickly saw that there was a different attitude- I remember distinctly a long flame-war with Caydr, because he didn't credit most of the people who made his mod's scripts, etc., and he just basically said, "meh, I don't remember, it doesn't matter, and who cares, I'm Caydr". And then people basically arguing that it was OK for them to steal whatever they wanted from whomever they wanted, because they believed that Spring was illegal because of the inclusion of Cavedog IP.
This was never my view, however insignificant my views are. Caydr was incorrect, hence long flame wars, just like this one. You've also got to realize that Caydr has a massive fanboi army, you do not.
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post by Tobi »

Felix the Cat wrote:Here's what I can say for sure:
-If you copy Bob's walk script and adjust it for use on your unit, Bob holds copyright to your adjusted script.
-If you copy Bob's walk script and make heavy modifications to improve it, Bob holds copyright to your adjusted script.
-If you copy Bob's walk script and do X to it, Bob holds copyright.
-If you read Bob's walk script and then reassemble it from memory, it is the same as copying it, and Bob holds copyright.
-If someone tells you how Bob's walk script works and you independently code it, you hold copyright.
Actually I'd say in the first four points the copyright state of the resulting script is just in an inconsistent state: Bob holds copyright to the original part. You hold copyright to the modifications. Because neither of you gave the other access to use each others stuff, neither of you is allowed to use the modified script. Nor is anyone else. So the only useful thing that can be done to it is either destroy it, or to rewrite all parts that originate from Bob in a totally independent manner, which is near impossible if you Bob's script was of reasonable size.

It'd be silly after all if you took a small piece of script that's copyrighted by Bob, you add like 10x more functionality to it, and in court it appears that everything you made is copyrighted by Bob because you happened to start with a 10 line script of Bob.

But you're right yeah about the 'copying from memory stuff' I think, because that's the reason some Linux hackers definitely did not want to see the Windows source when there was this myth that it had leaked: it could have weakened their position in court quite a lot.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

Argh wrote:In short, everybody seems to be under the impression that I want people to use my code, so that I can screw them over later, or something and this is completely wrong.
It is not an impression. It is what you did.



Argh wrote:I remember distinctly a long flame-war with Caydr, because he didn't credit most of the people who made his mod's scripts, etc., and he just basically said, "meh, I don't remember, it doesn't matter, and who cares, I'm Caydr"
Every time I've looked at the Absolute Annihilation files, I saw a text file with a very long list detailing all people and unit groups he took units from. Even back in the days Spring wasn't out and AA was a TA mod. Caydr was clear and honest about his mod being based of varied third party units grabbed from around the net. It is only the AA fanboys that the old TAU guards went made at for being too quick to forget that. This is can be proven by the following: Download AA. Unzip, look into /documentation/, open Manual.txt, and reads section 5 and 7. Which I'll quote here since no one would read them otherwise:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

[5] Credits:

Absolute Annihilation's Community
Brave Sir Robin (Uberhack)
Andrey Scherbakov (contributor)
StonedWolf (contributor)
Twilight (contributor)
Archangel (contributor, barbed marshmallow, Überscripter of teh doom)
Forboding Angel (contributor)

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

[6] Unit Groups:

Aftermath Design
Bethany Brand Units
C.A.N.A.D.A.
Cavedog
Central Consciousness
Core Prime
Immer
Killer TA Units
M.A.D. TA
Marcosoft
Mayhem Inc
Merciless Creations
P-We Division
Rat
Skunk Works
StoneAge Creations
TAAN/TAAN Upgrades
TA Bio Hazard
TA-Power
Taskforce
The Lost Legacy
Total Annihilation Generation
Total Annihilation R&D
Total Annihilation Units Creation Center
Total Annihilation War Factory
The Dojo
Tonic Rangers
Uberhack
Upstart Design Group
Unlimited Units
Water World Wars

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

[...]

[8] Legal/Disclaimer:

(1) I claim no ownership of the units included in this pack and acknowledge
their authors. I claim ownership only of how this pack is assembled,
and which particular units were included and/or modified.

[...]

Argh wrote:In regards to my commented GPL notice, I can certainly add that statement. Maybe then people will get a lot less antsy, if they know that my objective here is not to hunt people down who use my work but to prevent other people from privatizing my sourcecode.
  • You do hunt people who use your work.
  • How adding a GPL license makes your work less easy to steal? Has long as you publish, under whatever license, you can show you have prior art and nullyfying their privatisation.



Argh wrote:A .S3O is a non-random collection of data designed by a human being, and does not require the BOS script, nor does the BOS script necessarily require the .S3O. It's not like, say, some 3D renderer or whatever, where nothing can be excluded without destroying the whole thing, or severely changing the function.
I contest that. The bos script necessarily require the .S3O. The name of the piece, the distance between piece, the hierarchy of pieces, the initial positions of pieces, are stored in the s3o, and completly change the way the animation is played. A striking exemple would be the times when Zenka made a new model for the flea, then posted about how the walkscript wasn't working. Then I took his s3o, rerigged it (that is changing the pieces origin in the s3o), saved the s3o, and then the very same walkscript was suddenly "working". For a static rendering point of view, the s3o was appearing the same, the script wasn't touched, but some values in the s3o controlled the walk animation together with the script. So, the s3o is necessary for the script. And the other way around gor very complex and bushy s3o, the s3o doesn't make sense without a script that first hide lots of piece and move many piece in the Create(). But this case is much more rare.
Argh wrote:#define HEALTH 4 == #define ZWZSG_IS_A_FOOL_WHO_DOESNT_UNDERSTAND_BYTECODE 4 !!!
I find it quite funny that your peusdo code actually would make very little sense in a compiler.

Ok, in the below paragraph, you make it sound like the the only things left to change in your .h to make them entirely different from Cavedog's one, is the actual "bytecodes" such as the 4. Which is not what you did. You copied and pasted those headers. Oh wait, not even. You took those header, erased the copyright line and replaced it by yours.

Let's make this right:
- If you rewrote headers keeping only the numerical values of those 'get/set', I wouldn't said you stole Cavedog
- Moreso, if you rewrote headers keeping the numerical values AND the litteral name of the 'get/set', I would understand that litteral name are kept only so that old scripts still compile, and I wouldn't say you stole Cavedog and agreed to consider it your own work.
- If you kept the whole .h intact, including Cavedog's copyright, I wouldn't have said you stole Cavedog since you wouldn't be pretending they're your own.

However, when you keep everything including comments from Cavedog's original, it clearly shows you have not rewritten those headers, but merely take those headers and change the copyright lines. Then add a few lines at the bottom. And also merging two headers into one.

Maybe I would attack you for copylefting headers so simple they aren't copyrightable, but I wouldn't have said you stole Cavedog copyight. BTW, me saying those headers are not copyrightable is quite contradictory with me saying they are copyrighted by Cavedog. But that just makes you adding GPL license to them double times wrong.
Argh wrote:Plus you're accusing me of copyright violation and other criminal acts, which I find extremely offensive, since I took great pains to avoid any such problems, down to writing all new standard headers, smoke scripts, and other ancillary crap.
No, you did not went to great pain to write all new standard headers. You grabbed the existing standard header, removed the line about Cavedog copyright, and replaced it with your own copyright. The bulk of the files is taken identical straight from Cavedog.


jcnossen wrote:I trust zwzsg that the cavedog files contain the same definitions AND same comments on them, so that must mean that part of Argh's files is made by Cavedog and has cavedog copyright.
Please, don't make it a question of trust. That takes about 30 seconds to check, and that requires no modding degree.
zwzsg wrote:[list][*][list][*]Download NanoBlobs 0.64 GPL, either from:[list][*] Spring's download page's GPL content installer.
[*] unknown-files[/list]
While doing so, please notice the importance already given to words such as "GPL-compliant" or "licensed under GPL"
[*] Get 7-zip, or even a plain winzip.
[*] With 7-zip, open NanoBlobs064.sdz
[*] Count the number of files in the root of that zip whose filename end with license.txt
[*] Go into /scripts/, and open STANDARD_COMMANDS_GPL.h, notice the first two lines.[/list][*][list][*] Install Total Annihilation
[*] Get HPIView
[*] Run HPIView, file->open, and open totala1.hpi
[*] Go into /scripts/, and open sfxtype.h as well as sfxtype.h[/list][*]Compare[/list]

jcnossen wrote:However I'm not sure if cavedog has made them avaiable under a specific license.
Back in 1997, RTS weren't supposed to be moddable by third parties, and Total Annihilation was no execption. Cavedog made the game moddable for their own purpose, so that Cavedog website could propose a new unit to download every week. That fans would crack the TA files format and start making their own units wasn't expected. It is only years later that commercial games developper and publisher started to really take into account modding and to propose modding kit with appropriate license. Those .h were left in Totala1.hpi only because no one at a Cavedog took the time to properly clean the TA data files of all source code and other unused ressources. It wasn't an offering to the modding community, just a left-over from the production. As proved by how they didn't include all files scripts reference to, and how they made sure to remove all bos and .h in the data of the subsequents add-ons such as Core Contingency, Battle Tactics, and the 3.1c patch units (but not all of six last, they prolly were rushed). From their point of view, it made sense to not take the time to properly delete those files, since
  • No one was supposed to crack open hpi and notice.
  • By deleting unused files, they would have taken the risk to also delete used files and break the games.
  • That'd take some worker times for no added values.
  • Filesizes wise, they are negligible
Then when TA fans started to release their own fan-made script compiler, they bundled it with those headers they found and extracted from totala1.hpi. Because it's quite useful to be able to write "FIRE" instead of "16" for instance. And it made writing third party unit script more similar to writing Cavedog's script, and in those time the goal was to make it easier to write script, not to differientate from Cavedog. Well, I wasn't around during the time of early TA modding, so I'm just guessing it went like that. But at least, unlike Argh, they had the decency to keep the Cavedog Copyright line. Even if for TA modding, probably no one cared about copyright and licensing. There's been a couple third party modellers who went mad when there models was reused by someone else, but scripting was a technical stuff that wasn't immediatly recognisable in the end products, scripter were rare, and people reused each other scripts with little concerns with autorship and copyrights.

Tobi wrote:Also I think it has been ruled in court already that a set of #defines can not be copyrighted (in the SCO vs IBM case).
Yeah, I think so to. As I said in my second post here. That is the second, different from the first, reason why Arg's licensing them under GPL is wrong.

KDR_11k wrote:BTW, Kernel Panic is public domain AFAIK.
Well, besides a few forum posts by you and Boirunner, there's nothing that indicate it. Maybe it's time we included some proper licensing declaration in it, for next version?





There is still one thing we must grant to Argh, is that he is one of the very people who actually was concerned with giving proper legal ground to mods files, and to frame sharing of scripts from a mod to the other with legally grounded text. Considering how even know mods blatantly ripping Cavedog's IP are the most numerous and popular, that is a welcomable move. The only issue, is that why his intent are noble, the method used was wrong. Whether it's due to a lack of skill, to malice, or to how he accounted on no one checking, his .h and .bos are still too heavily derived from Cavedog.

Actually, nearly all mods, not just TA based ones by even mods such as Gundam, Expand & Exterminate, 1944, have scripts that are as heavily based on Cavedog's script than Argh's nanoblobs. The only differences are that:
  • They don't claim all their scripts are brand new scripts.
  • They don't use the acronym GPL everywhere
  • They don't claim their script are protected by GPL.
  • They don't hunt down other modders borrowing their scripts.
Imo, it would be best for everybody to consider that simple scripts and Cavedog-alike scripts are too simple to be copyrighted. For very complex and very innovative scripts, I don't know, I guess I could accept either way, have them copyrigthable, or have them free for anyone to reuse.
Technically, most scripts are almost like a data sheet following a template. However, sripting is a programming language in its own right, and one can write actual lengthy and arduous program in it. It just happens very rarely.

Ok, to show more what I'm talking about, here's an exerpt from Argh's NanoBlobs064.sdz/scripts/sheep.bos

Code: Select all

QueryNanoPiece(piecenum)
{
	piecenum = sprayer;
}
The word "sprayer" refers to a name of the piece in the 3do or s3o. About every modder know and do change it to reflect his own model.

The word "piecenum" is a function argument and local variable. It can be changed, personnaly I use "p" instead of "piecenum", and the script will work the same. It'll even compile into a stricly identical COB. However, about every scripter beside me keep the same name as in Cavedog script. There can be many reason for most scripts keeping the same "piecenum" name: Many modders are too afraid to touch scripts code and limit themselves to changing as few thing as possible. The name used has zero impact on anything, so why change it? Sticking to tradionnal names makes script more easily written by fellows modders, this is more comfortable when variables show the same naming convention accross different people work. This shows that Argh did not follow chinese room method. That is script are made from Cavedog bos. That they are not rewritten to comply to Spring's specification, but are copy'n'pasted. I'm fine with people following Cavedog's tradition when it comes to variable naming. But then don't pretend to have all new code written from scratch, only ressembling to Cavedog's script because you followed specification hard coded into the exe.

The word "QueryNanoPiece" cannot be changed. That same name is also hard coded into Totala.exe and Spring.exe. That word must be kept exactly as it is, even capitalisation, as it used by the engine to find out which portion of the script to execute to ask the script where nano should be flowing from.

But when it comes to algorithm, there is about none. This, imo, perfectly show why I believe simple scripts should not fall under the scope of GPLable code licensing.

From a more technical point of view, what I mean is that the difficulty of writing that particular code is almost only adhering to the funtion specification & declaration. In C++, the function specification & declaration are written in .h files. And they are not copyrithable. We're only following the same function specification & declaration as in Cavedog because we want Spring to maintain compatibility with Spring. Imo, this is perfectly ok and doesn't require rewritting. This is also no copyritable nor copyleftable. The only actual code is an affectation. Which is clearly not a copyritable algorithm.


In more understable term, what I mean is that the role of that function could very well be replaced by a FBI tag. Just, somehow, Cavedog had everything referring to piece placed in similar short script function instead of FBI tags.

For a standard tank, the most complex and longest function (beside the Killed) is the aiming function. Here's the one from Cavedog Arm Stumpy, totala1.hpi/scripts/ArmStump.bos

Code: Select all

AimPrimary(heading,pitch)
	{
	signal SIG_AIM;
	set-signal-mask SIG_AIM;
	turn turret to y-axis heading speed <90>;
	turn barrel to x-axis (0-pitch) speed <50>;
	wait-for-turn turret around y-axis;
	wait-for-turn barrel around x-axis;
	start-script RestoreAfterDelay();
	return(TRUE);
	}
So, the name "AimPrimary" must stay because it's also hard coded into TotalA.exe and Spring.exe. Well, ok, in Spring you can change it into "AimWeapon1", but that's still two names hard coded into the exe you have to adhere to.

The names of
- The argument / local variable, heading and pitch
- The #define'd contant, SIG_AIM,
- The function only called/started by other script function and not directly by the engine, RestoreAfterDelay()
Are incidental, and can be changed to whatever, while still giving the exact same result.
The names "heading", "pitch", and "SIG_AIM", can be changed and the BOS will still compile into a stricly identical byte-by-byte COB. If the function name "RestoreAfterDelay()", ok the COB isn't identical byte by byte, but works exactly the same. Most scripter follow the tradition of keeping the names "heading" and "pitch" and "SIG_AIM" and "RestoreAfterDelay()". We could assume it's merely for clarity and for not destabilizing potential readers with unconventionnal names.


The names of the pieces, "turret" and "barrel", can be changed to reflect the 3do piece names. About every scripter knows he has to change them to match his model piece names. But then, the name "turret" and "barrel" are still pretty commonly kept, because they make sense, and also because sticking to tradionnal names makes script more readable.

The values <90> and <50> are off course changeable, they will make the unit aim faster or slower. I think everybody writing script knwo and will change them. Well, I guess that doesn't event warrant that line of explanation.


The algorithm:

FuctionName(argument1,argument2)
{
use a signal command to kill previous instances of that function
set a signal flag to make this function kill-able
make the turret piece starts turning, at a given speed, along vertical axis, up to the angle specificed by the engine
make the child piece of the turret starts turning, at a given speed, along transversal axis, up to the angle specificed by the engine
wait until the turret has reached position
wait till child of turret has also reached position
start a script that will make the turret goes back to a resting postion if the unit is no more fighting for a long time
return with the value 1, where the 1 indicate the engine it all went well and the authorisatio to fire is granted
}

is actually pretty simple and there's not many other way to write it. Trying to use another algorithem would probably be very complex, buggy, wouldn't do the job as well for a simple turret, etc.. the values, such as the rotation speed or the names of pieces, about every scripter know and will change already. The formula such as 0 - pitch, and the axis, you have to keep, at least if your 3do depict a regular tank with the gun pointing forward. If in your 3do/s3o the gun was pointing sideward, or upward, or backward, or downard, you'd use different axis and different "formula", if can something like "<90> - heading" a formula.

Once, I used another way than the "wait-for" to check the piece had reached desired angle. Here's what I used that one time:

Code: Select all

AimSecondary(heading,pitch)
	{
	signal SIG_SECONDARY;
	set-signal-mask SIG_SECONDARY;
	while(!charger_around)
		{
		sleep 200;
		}
	time_since_last_aiming=0;
	var anglediff, rottime;
	anglediff=get XZ_ATAN(get PIECE_XZ(turret) - get PIECE_XZ(turret_angle_marker)) - heading;
	turn turret to y-axis heading speed <60>;
	turn turret to x-axis 0 - pitch speed <40>;
	while(anglediff<0)
		{anglediff=anglediff + 65536;}
	while(anglediff>32768)
		{anglediff=anglediff - 65536;}
	anglediff=anglediff*(1 - 2*(anglediff<0));
	sleep anglediff*1000/(<60>);
	return(1);
	}
But this more complex and far-fetched, and doesn't work very well when the tank is on a steep slope. I think we can agree that using "wait-for" is much simpler and straighforward.

Well, what I'm aiming at, is that when writing an aiming script, if you want to keep things simple an straightforward, there isn't really that many way around and I suspect your script will either ressemble to Cavedog script or not work as well.


Here is the aiming of Argh's NanoBlobs064.sdz/scripts/Wolf.bos

Code: Select all

AimPrimary(heading, pitch)
{
	signal SIG_AIM1;
	set-signal-mask SIG_AIM1;
	turn gunassembly to x-axis 0 - pitch speed <600>;
	wait-for-turn gunassembly around x-axis;
	start-script RestoreAfterDelay();
	return(TRUE);
}
As can be seen, he removed two lines, but otherwise kept not only the algorithm and the hard coded names, but also the incidental variable, constant, and function names, that could have been changed without any impact. And yes, the fist three lines of that script are:

Code: Select all

// Argh's GPL Wolf Script

// This script is released under the terms of the GNU license.  
// All contents were created by Wolfe Games.

Ok, to be more fair, some of his aiming script are a little different, such as the SpireRook:

Code: Select all

AimWeapon1(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);
}
here you see he has added some "if" so the turrets aims differetly depending if it is aiming upward or downad, leftward or downard. Hmm, since spring used signed angles, that does nothing more than a regular aiming script, but if it was for TA, that would have make the script turn the turret in the different, opposite, direction depending if the target is downard or upward, depending if the target is leftward or rightward. But otherwise it follow the same template as a Cavedog script, and even the same variable and contant and function names (for the RestoreAfterDelay(), as AimWeapon1 has to be kept and isn't even the Cavedog name.)


I'll spare you the walk scripts, but similarly, Argh has followed Cavedog algorithm and variable names with more but still little changes.


What I wanted to show, is that:
1) Regular scripts function are often so simple they aren't that many ways for programming creativity. So no copyrights.
2) Argh's scripts are mere copies of Cavedog scripts, he kept even what was fully incidentable and changeable.

Well, since so far very few of people posting here have recognised that:
- Argh's .h are copies of Cavedog's .h
- .h are too simple to be copyrightable
I guess even less have followed this demonstration that:
- Argh's .bos are copies of Cavedog's .bos
- Regular, simple, .bos are too simple to be copyrightable

But at least, it's here, for the record. Felt I had to prove it since quite a few times I hinted that his bos are too heavily based on Cavedog's bos to be copyrightable, and most bos are too simple to be copyritable material.

For the record, here is an exemple of a bos that:
- Use the same commands and syntax and even standard get/set as Cavedog bos.
- Use the function name "TransportDrop" because it is hardcoded in the engine.
- Does not use any algorithm or method from any Cavedog bos
- Does not use any copy'n'paste from Cavedog code
- Was typed character by character, from scratch.
- Use some actual algorithm, and non-trivial code.
- Does not have any lines that is the same as in Cavedog script, beside closin bracket. *
- So, could actually fall under the scope of copyritable program (though I'd rather have all bos non copyrithable actually)

* Actually, when it has, "set BUSY to 1;", it's very close from Cavedog's "set BUSY to TRUE;", when it has "attach-unit unit_to_auto_unload to 0 - 1; it's very close from Cavedog's "attach-unit unitid to 0-1;", when it has "sleep 2000;", it is very close from any Cavedog's "sleep 5000;". And when I wrote that script, my goal wasn't to make sure I had not lines the same as in any Cavedog script. I was just writing some autounload to replace traditionnal one unit at a time unload. So, maybe, by looking very close, you could find some identical lines. Also, if changing numerical values or piece names or a variable does not make a line different, then lines like "drop-unit id;" or "return;" are the same because they are elementary commands.

Yet, it shows, than when you rewrite instead of copy'n'paste, when you devise new algorithms instead of following Cavedog's templates, it actually looks different from Cavedog's script.

Taken from http://wormhole.tauniverse.com ArmDuck

Code: Select all

// I spare you the pages of custom macros, includes, and defined constants.

TransportDrop(unit_to_manual_unload, position_to_manual_unload)
	{
	#if DECLARE_ALL_LOCAL_VARS_AT_BEGINNING
	
	#if LIMITED_CARGO_HOLD
	var h, w, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11;
	#else
	var val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11;
	#endif
	
	#define distance_to_wanted_manual_unload_position val1
	
	#define unit_to_auto_unload val1
	#define z_to_unload val2
	#define x_to_unload val3
	#define pos_on_row val4
	#define num_row val5
	#define radius_to_unload val2
	#define angle_to_unload val3
	#define pos_on_circle val4
	#define num_circle val5
	#define max_pos val6
	#define same val7
	#define last_goal val8
	#define shape val9
	// because h and w are used in a macro #defined inside the H2WEIGHT.h that is #included at the very beginning, h and w can't be #defined but have to be declared
	
	#else
	
	#if LIMITED_CARGO_HOLD
	var h,w;
	#endif
	
	#endif
	
	#if (GROUP_UNLOAD==1)
	if(units_inside<=0 || units_inside>MAX_UNITS_INSIDE)// If manual unload or if unit to unload unregistered
		{
	#endif
		// Manual Unload:
		#if !DECLARE_ALL_LOCAL_VARS_AT_BEGINNING
		var distance_to_wanted_manual_unload_position;
		#endif
		distance_to_wanted_manual_unload_position=get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - position_to_manual_unload);
		if(distance_to_wanted_manual_unload_position<MANUAL_UNLOAD_MINIMUM_RADIUS)
			{
			distance_to_wanted_manual_unload_position=MANUAL_UNLOAD_MINIMUM_RADIUS;
			}
		if(distance_to_wanted_manual_unload_position<=MANUAL_UNLOAD_MAXIMUM_RADIUS)
			{
			set BUSY to 1;
			OPENING_DOOR_ANIMATION
			turn unload_shoulder to y-axis get XZ_ATAN(get PIECE_XZ(unload_shoulder) - position_to_manual_unload) now;
			move unload_arm to x-axis 0 now;
			move unload_arm to y-axis 0 now;
			#if !INSTA_UNLOAD
			move unload_arm to z-axis DISAPPEAR_RADIUS now;
			#endif
			turn unload_arm to y-axis get XZ_ATAN(get PIECE_XZ(unload_shoulder) - position_to_manual_unload) now;
			#if !INSTA_UNLOAD
			attach-unit unit_to_manual_unload to unload_arm;
			move unload_arm to z-axis distance_to_wanted_manual_unload_position speed MANUAL_UNLOAD_SPEED;
			move unload_arm to y-axis get GROUND_HEIGHT(position_to_manual_unload) - get PIECE_Y(unload_shoulder) speed (1 - 2*(get GROUND_HEIGHT(position_to_manual_unload) < get PIECE_Y(unload_shoulder)))*(((((get GROUND_HEIGHT(position_to_manual_unload) - get PIECE_Y(unload_shoulder))*48) / get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - position_to_manual_unload)) * MANUAL_UNLOAD_SPEED)/48);// K, have fun deciphering this one!
			#endif
			#if INSTA_UNLOAD// hash-if !VALUE ... hash-else makes Scriptor fails. And hash-if in comments are counted!
			move unload_arm to z-axis distance_to_wanted_manual_unload_position now;
			move unload_arm to y-axis get GROUND_HEIGHT(position_to_manual_unload) - get PIECE_Y(unload_shoulder) now;
			attach-unit unit_to_manual_unload to unload_arm;
			#endif
			wait-for-move unload_arm along z-axis;
			drop-unit unit_to_manual_unload;
			--units_inside;
			#if LIMITED_CARGO_HOLD
			h=get UNIT_HEIGHT(unit_to_manual_unload);
			CALC_WEIGHT;
			cargo_hold=cargo_hold - w;
			#endif
			#if !INSTA_UNLOAD
			sleep 1;
			#endif
			move unload_arm to z-axis 0 now;
			move unload_arm to y-axis 0 now;
			sleep 1;//wait-for-move unload_arm along z-axis;
			if(get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - get UNIT_XZ(unit_to_manual_unload))<=TOLERANCE)//If it failed dropping
				{
				attach-unit unit_to_manual_unload to 0 - 1;
				++units_inside;
				#if LIMITED_CARGO_HOLD
				h=get UNIT_HEIGHT(unit_to_manual_unload);
				CALC_WEIGHT;
				cargo_hold=cargo_hold + w;
				#endif
				}
			#if ((EXPLODE_WHEN_UNLOADING) || (FLAME_WHEN_UNLOADING))
			if(!(get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - get UNIT_XZ(unit_to_manual_unload))<=TOLERANCE))//If it succeed dropping
				{
				move unload_arm to z-axis distance_to_wanted_manual_unload_position now;
				move unload_arm to y-axis get GROUND_HEIGHT(position_to_manual_unload) - get PIECE_Y(unload_shoulder) now;
				#if EXPLODE_WHEN_UNLOADING
				explode unload_arm type BITMAPONLY | BITMAP2;
				#endif
				#if FLAME_WHEN_UNLOADING
				emit-sfx SFXTYPE_VTOL from unload_arm;
				#endif
				move unload_arm to z-axis 0 now;
				move unload_arm to y-axis 0 now;
				}
			#endif
			#if !INSTA_UNLOAD
			sleep 100;
			#endif
			CLOSING_DOOR_ANIMATION
			set BUSY to 0;
			}
	#if GROUP_UNLOAD
		return;
		}// end Manual Unload
	
	
	
	// Auto Unload:
	
	#if !DECLARE_ALL_LOCAL_VARS_AT_BEGINNING
	var unit_to_auto_unload, val1, val2, val3, val4, val5, same, last_goal, shape;
	#define z_to_unload val1
	#define x_to_unload val2
	#define pos_on_row val3
	#define num_row val4
	#define radius_to_unload val1
	#define angle_to_unload val2
	#define pos_on_circle val3
	#define num_circle val4
	#define max_pos val5
	// those define were so rectangular and multi circular use the same variables but under different names, because there is a limit to the number of local variable there can be in a TA script
	#endif
	
	if(get XZ_HYPOT(get PIECE_XZ(base) - position_to_manual_unload)>AUTO_UNLOAD_MAX_DISTANCE_BEFORE_STARTING)
		{
		sleep 120;
		return;
		}
	
	//shape=(get XZ_HYPOT(get PIECE_XZ(base) - position_to_manual_unload)>[8]) && ((((get XZ_ATAN(get PIECE_XZ(base) - position_to_manual_unload)>0 - 16384) && (get XZ_ATAN(get PIECE_XZ(base) - position_to_manual_unload)< 16384)) || (get XZ_ATAN(get PIECE_XZ(base) - position_to_manual_unload)> 49152)));
	shape=(get XZ_HYPOT(get PIECE_XZ(base) - position_to_manual_unload)>[8])*(((((get XZ_ATAN(get PIECE_XZ(base) - position_to_manual_unload)>0 - 16384) && (get XZ_ATAN(get PIECE_XZ(base) - position_to_manual_unload)< 16384)) || (get XZ_ATAN(get PIECE_XZ(base) - position_to_manual_unload)> 49152)))-3)+3;
//
//	The variable shape determine the shape of the formation. It can only be 0,1, or 2.
//	The currrent formula makes it uses shape 0 when clicking behind, shape 1 when clicking in front, and shape 3 when clicking center. The current formula doesn't use shape 2, as I feel shape 1 is like shape 2 but much better.
//
//		Shape==0 		Shape==1 		Shape==2	Shape==3
//		   ooo   		
//		  oxxxo  		+++++++++		+++++		ooooooo
//		 ox213xo 		+ooooooo+		ooooo		oxxxxxo
//		ox4   5xo		+oxxxxxo+		xxxxx		ox213xo
//		ox6   7xo		+ox546xo+		97680		ox405xo
//	 	 ox809xo 		+ox213xo+		42135		ox687xo
//		  oxxxo  									oxxxxxo
//		   ooo   									ooooooo
	
	set BUSY to 1;
	OPENING_DOOR_ANIMATION
	#if QUIT_AUTO_UNLOAD_WHEN_MOVING
	while(is_moving)
		{
		sleep 100;
		}
	#endif
	
	if(shape==0)
		{
		num_circle=0;
		pos_on_circle=0;
		same=FALSE;
		}

	if(shape==1)
		{
		num_row=0;
		pos_on_row=0;
		same=FALSE;
		}
	
	if(shape==2)
		{
		num_row=0;
		pos_on_row=0;
		same=FALSE;
		}
	
	if(shape==3)
		{
		num_row=AUTO_UNLOAD_FIRST_ROW;
		pos_on_row=0;
		same=FALSE;
		}

	while(units_inside>0)
		{
		if(shape==0)
			{
			radius_to_unload=(AUTO_UNLOAD_FIRST_RADIUS) + (num_circle * (AUTO_UNLOAD_RADIUS_INCREMENT));
			max_pos=(((radius_to_unload/1000)*6283)/AUTO_UNLOAD_ARC_LENGTH);// This is tricky: we must not go over 2^31, yet we must always have numbers much greater than 1 (otherwise decimals are lost)
			angle_to_unload=((pos_on_circle+1)/2)*65536/max_pos;
			// max_number_of_pos_per_circle = radius*2pi/ arc_between_each_pos
			// angle to unload = (half-position / max_number_of_pos_per_circle) * angle_of_full_turn
			//     half position because each even numbered pos is the same as the odd one just with a minus sign
			//     and multiplication before division to avoid losing the decimal since scripts can only handle integers
			//     and +1 to pos so pos 0 and pos 1 aren't on same null angle but only 0 is
			if(((pos_on_circle/2)*2)==pos_on_circle)
				{
				angle_to_unload=0 - angle_to_unload;
				}
			if(((num_circle/2)*2)!=num_circle)
				{
				angle_to_unload=angle_to_unload - 32768/max_pos;
				}
			turn goal_shoulder to y-axis angle_to_unload now;
			move goal_arm to z-axis radius_to_unload now;
			move goal_arm to x-axis 0 now;
			}
		if(shape==1)
			{
//		+++++++++
//		+LJHGIKM+
//		+ExxxxxF+
//		+Cx546xD+
//		+Ax213xB+
			if(pos_on_row<2*num_row)
				{
				z_to_unload=((pos_on_row/2)*AUTO_UNLOAD_FRONT_SPACING)+AUTO_UNLOAD_DISTANCE_FIRST_ROW;
				x_to_unload=((2*(((pos_on_row+1)/2)==((pos_on_row+2)/2))-1)*num_row)*AUTO_UNLOAD_SIDE_SPACING;
				}
			if(pos_on_row>=2*num_row)
				{
				z_to_unload=(num_row * (AUTO_UNLOAD_FRONT_SPACING))+AUTO_UNLOAD_DISTANCE_FIRST_ROW;
				x_to_unload=(2*(((pos_on_row+1)/2)==((pos_on_row+2)/2))-1)*((pos_on_row +1 - 2*num_row)/2)*AUTO_UNLOAD_SIDE_SPACING;
				}
			turn goal_shoulder to y-axis 0 now;
			move goal_arm to z-axis z_to_unload now;
			move goal_arm to x-axis x_to_unload now;
			}
		if(shape==2)
			{
			z_to_unload=(AUTO_UNLOAD_DISTANCE_FIRST_ROW) + (num_row * (AUTO_UNLOAD_FRONT_SPACING));
			x_to_unload=((1+pos_on_row)/2)*AUTO_UNLOAD_SIDE_SPACING;
			if(((pos_on_row/2)*2)!=pos_on_row)
				{
				x_to_unload=0 - x_to_unload;
				}
			if((AUTO_UNLOAD_UNITS_PER_ROW/2)*2==AUTO_UNLOAD_UNITS_PER_ROW)
				{
				x_to_unload=x_to_unload + AUTO_UNLOAD_SIDE_SPACING/2;
				}
			turn goal_shoulder to y-axis 0 now;
			move goal_arm to z-axis z_to_unload now;
			move goal_arm to x-axis x_to_unload now;
			}
		if(shape==3)
			{
			// num_row = number of the onion ring
			// num_row = 0 -> the first ring, with 1 spot
			// num_row = 1 -> the first ring, with 8 spot
			// num_row = 2 -> the first ring, with 16 spot
			// num_row = 3 -> the first ring, with 24 spot
			//
			// pos_on_row = from 0 to max_pos, reset to 0 at each row
			//
			// max_pos= 0, 7, 15,23, ...
			//
			max_pos=8*num_row - (num_row!=0);
			if(pos_on_row<=(num_row*2))// The front line, including corners
				{
				z_to_unload=num_row * AUTO_UNLOAD_SIDE_INCREMENT;
				x_to_unload=(1-2*((pos_on_row/2)*2==pos_on_row))*((pos_on_row+1)/2)* AUTO_UNLOAD_SIDE_INCREMENT;
				}
			if((pos_on_row>(num_row*2)) && (pos_on_row<6*num_row -1))// The two side lines, excluding corners
				{
				z_to_unload=(2*num_row -((pos_on_row+1)/2))*AUTO_UNLOAD_SIDE_INCREMENT;
				x_to_unload=(1-2*((pos_on_row/2)*2==pos_on_row))*(num_row* AUTO_UNLOAD_SIDE_INCREMENT);
				}
			if(pos_on_row>=6*num_row -1)// The back line, including corners
				{
				z_to_unload= 0 - num_row * AUTO_UNLOAD_SIDE_INCREMENT;
				x_to_unload=(1-2*((pos_on_row/2)*2==pos_on_row))*((pos_on_row - 8*num_row)/2)* AUTO_UNLOAD_SIDE_INCREMENT;
				}
			turn goal_shoulder to y-axis 0 now;
			move goal_arm to z-axis z_to_unload now;
			move goal_arm to x-axis x_to_unload now;
			}
		
		if(get XZ_HYPOT(get PIECE_XZ(base) - get PIECE_XZ(goal_arm))>AUTO_UNLOAD_MAXIMUM_RADIUS)
			{
			// The goal is too far and TotalA.exe risk crashing if we move an attached unit there
			CLOSING_DOOR_ANIMATION
			set BUSY to 1;
			sleep 2000;
			set BUSY to 0;
			return;
			}
		#if !INSTA_UNLOAD
		turn unload_shoulder to y-axis 0 now;
		move unload_arm to x-axis 0 now;
		move unload_arm to y-axis 0 now;
		move unload_arm to z-axis 0 now;
		turn unload_arm to y-axis 0 now;
		wait-for-move unload_arm along z-axis;
		#endif
		
		GET_ID_TO_UNLOAD(unit_to_auto_unload)
		while((get XZ_HYPOT(get PIECE_XZ(base) - get UNIT_XZ(unit_to_auto_unload))>TOLERANCE) && (get XZ_HYPOT(get PIECE_XZ(load_shoulder) - get UNIT_XZ(unit_to_auto_unload))>TOLERANCE) && (get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - get UNIT_XZ(unit_to_auto_unload))>TOLERANCE))// If the unit we got the ID of has been stolen, then get the next ID
			{
			--units_inside;
			#if LIMITED_CARGO_HOLD
			h=get UNIT_HEIGHT(unit_to_auto_unload);
			CALC_WEIGHT;
			cargo_hold=cargo_hold - w;
			#endif
			if(units_inside<=0)
				{
				CLOSING_DOOR_ANIMATION
				set BUSY to 0;
				return;
				}
			GET_ID_TO_UNLOAD(unit_to_auto_unload)
			}
		#if !INSTA_UNLOAD
		if(!same)
			{
			turn unload_shoulder to y-axis get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) now;
			move unload_arm to x-axis 0 now;
			move unload_arm to y-axis 0 now;
			move unload_arm to z-axis DISAPPEAR_RADIUS now;
			turn unload_arm to y-axis get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) now;
			}
		if(same)
			{
			turn unload_shoulder to y-axis get XZ_ATAN(get PIECE_XZ(unload_shoulder) - last_goal) now;
			move unload_arm to x-axis 0 now;
			move unload_arm to z-axis get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - last_goal) now;
			move unload_arm to y-axis get GROUND_HEIGHT(last_goal) - get PIECE_Y(unload_shoulder) now;;
			turn unload_arm to y-axis get XZ_ATAN(last_goal - get PIECE_XZ(goal_arm)) now;
			wait-for-move unload_arm along z-axis;
			attach-unit unit_to_auto_unload to unload_arm;
			turn unload_shoulder to y-axis get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) speed (shape!=0)*(AUTO_UNLOAD_SQUARE_CORRECTION_ANGULAR_SPEED)+(shape==0)*(AUTO_UNLOAD_CIRCLE_CORRECTION_ANGULAR_SPEED);
			wait-for-turn unload_shoulder around y-axis;
			}
		last_goal=get PIECE_XZ(goal_arm);
		
		attach-unit unit_to_auto_unload to unload_arm;
		sleep 1;
		if (get XZ_HYPOT(get UNIT_XZ(unit_to_auto_unload) - get PIECE_XZ(base))>TOLERANCE)// If it is not the transport itself
			{
			move unload_arm to z-axis get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) speed AUTO_UNLOAD_SPEED;
			move unload_arm to y-axis get GROUND_HEIGHT(get PIECE_XZ(goal_arm)) - get PIECE_Y(unload_shoulder) speed (1 - 2*(get GROUND_HEIGHT(get PIECE_XZ(goal_arm)) < get PIECE_Y(unload_shoulder)))*(((((get GROUND_HEIGHT(get PIECE_XZ(goal_arm)) - get PIECE_Y(unload_shoulder))*48) / get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))) * AUTO_UNLOAD_SPEED)/48);// K, have fun deciphering this one!
			wait-for-move unload_arm along z-axis;
			turn unload_arm to y-axis 0 now;
			if(shape==0)
				{
				turn unload_arm to y-axis (get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))<32768)*(get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))*AUTO_UNLOAD_RADIAL_PROPORTION)+(get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))>=32768)*((get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) - 65536)*AUTO_UNLOAD_RADIAL_PROPORTION) now;
				if (pos_on_circle==max_pos - 1)
					{
					turn unload_arm to y-axis 32768*((32768*AUTO_UNLOAD_RADIAL_PROPORTION>=16384) || (32768*AUTO_UNLOAD_RADIAL_PROPORTION<=0 - 16384)) now;
					}
				}
			if(shape==3)
				{
				turn unload_arm to y-axis (get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))<32768)*(get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))*AUTO_UNLOAD_SR_PROPORTION)+(get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))>=32768)*((get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) - 65536)*AUTO_UNLOAD_SR_PROPORTION) now;
				if (pos_on_circle==max_pos)
					{
					turn unload_arm to y-axis 32768*((32768*AUTO_UNLOAD_SR_PROPORTION>=16384) || (32768*AUTO_UNLOAD_SR_PROPORTION<=0 - 16384)) now;
					}
				}
			wait-for-turn unload_arm around y-axis;
			#endif
		#if INSTA_UNLOAD// hash-if !VALUE ... hash-else makes Scriptor fails. And hash-if in comments are counted!
		turn unload_shoulder to y-axis get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) now;
		move unload_arm to x-axis 0 now;
		move unload_arm to y-axis get GROUND_HEIGHT(get PIECE_XZ(goal_arm)) - get PIECE_Y(unload_shoulder) now;
		move unload_arm to z-axis get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) now;
		turn unload_arm to y-axis 0 now;
		if(shape==0)
			{
			turn unload_arm to y-axis (get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))<32768)*(get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))*AUTO_UNLOAD_RADIAL_PROPORTION)+(get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))>=32768)*((get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) - 65536)*AUTO_UNLOAD_RADIAL_PROPORTION) now;
			if (pos_on_circle==max_pos - 1)
				{
				turn unload_arm to y-axis 32768*((32768*AUTO_UNLOAD_RADIAL_PROPORTION>=16384) || (32768*AUTO_UNLOAD_RADIAL_PROPORTION<=0 - 16384)) now;
				}
			}
		if(shape==3)
				{
				turn unload_arm to y-axis (get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))<32768)*(get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))*AUTO_UNLOAD_SR_PROPORTION)+(get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm))>=32768)*((get XZ_ATAN(get PIECE_XZ(unload_shoulder) - get PIECE_XZ(goal_arm)) - 65536)*AUTO_UNLOAD_SR_PROPORTION) now;
				if (pos_on_row==max_pos)
					{
					turn unload_arm to y-axis 32768*((32768*AUTO_UNLOAD_SR_PROPORTION>=16384) || (32768*AUTO_UNLOAD_SR_PROPORTION<=0 - 16384)) now;
					}
				}
		attach-unit unit_to_auto_unload to unload_arm;
		sleep 1;
		if (get XZ_HYPOT(get UNIT_XZ(unit_to_auto_unload) - get PIECE_XZ(base))>TOLERANCE)// If it is not the transport itself
			{
			#endif
		
			drop-unit unit_to_auto_unload;
			--units_inside;
			#if LIMITED_CARGO_HOLD
			h=get UNIT_HEIGHT(unit_to_auto_unload);
			CALC_WEIGHT;
			cargo_hold=cargo_hold - w;
			#endif
			#if !INSTA_UNLOAD
			sleep 1;
			#endif
			move unload_arm to z-axis 0 now;
			move unload_arm to y-axis 0 now;
			wait-for-move unload_arm along z-axis;
			same=FALSE;
			if(get XZ_HYPOT(get PIECE_XZ(unload_shoulder) - get UNIT_XZ(unit_to_auto_unload))<=TOLERANCE)//If it failed dropping
				{
				same=TRUE;
				++units_inside;
				#if LIMITED_CARGO_HOLD
				h=get UNIT_HEIGHT(unit_to_auto_unload);
				CALC_WEIGHT;
				cargo_hold=cargo_hold + w;
				#endif
				attach-unit unit_to_auto_unload to 0 - 1;
				}
			#if EXPLODE_WHEN_UNLOADING
			if(!same)
				{
				explode goal_arm type BITMAPONLY | BITMAP2;
				}
			#endif
			#if FLAME_WHEN_UNLOADING
			if(!same)
				{
				emit-sfx SFXTYPE_VTOL from goal_arm;
				}
			#endif
			if(shape==0)
				{
				++pos_on_circle;
				if(pos_on_circle>=max_pos)
					{
					pos_on_circle=0;
					++num_circle;
					}
				}
			if(shape==1)
				{
				++pos_on_row;
				if(pos_on_row>=4*num_row+1)
					{
					pos_on_row=0;
					++num_row;
					}
				}
			if(shape==2)
				{
				++pos_on_row;
				if(pos_on_row>=AUTO_UNLOAD_UNITS_PER_ROW)
					{
					pos_on_row=0;
					++num_row;
					}
				}
			if(shape==3)
				{
				++pos_on_row;
				if(pos_on_row>max_pos)
					{
					pos_on_row=0;
					++num_row;
					}
				}//end last shape choice
			}//end not the transport itself// Can't happen when ID are stored, but anyway
		#if QUIT_AUTO_UNLOAD_WHEN_MOVING
		if(is_moving)// It is important to note that the TransportDrop() is called as soon as the transport starts decelerating, sometimes long before it's fully stopped. And that StopMoving that set is_moving to FALSE is only called when it's fully stopped. So there's some wait till full stop up there.
			{
			CLOSING_DOOR_ANIMATION
			set BUSY to 0;
			return;
			}
		#endif
		}//end while(units_inside>0)
	CLOSING_DOOR_ANIMATION
	set BUSY to 0;
	return;
	#endif
	}
Fark, despite holding myself so far after all I couldn't prevent myself for showing off with my scripts. :S


The corresponding Cavedog's script would be totala1.hpi/scripts/ArmTShip.bos

Code: Select all

BoomCalc(posxz,posy)
	{
	var dxz,dy,lenxz;

	dxz = get PIECE_XZ(turret) - posxz;
	dy = posy - get PIECE_Y(turret) - [20];
	lenxz = get XZ_HYPOT(dxz);

	boom_len = get HYPOT(lenxz,dy) - [20];
	boom_heading = get XZ_ATAN(dxz);
	boom_pitch = get ATAN(dy,lenxz);
	boom_ok = (boom_len < [80]);
	}


BoomExtend()
	{
	start-script StartDoorOpen();

	turn turret to y-axis boom_heading speed <80>;
	turn magnet to x-axis boom_pitch speed <40>;
	turn arm1 to x-axis 0-boom_pitch speed <40>;
	move arm2 to z-axis boom_len/4 speed [30];
	move arm3 to z-axis boom_len/4 speed [30];
	move arm4 to z-axis boom_len/4 speed [30];
	move arm5 to z-axis boom_len/4 speed [30];

	wait-for-turn turret around y-axis;
	wait-for-turn arm1 around x-axis;
	wait-for-move arm2 along z-axis;
	wait-for-move arm3 along z-axis;
	wait-for-move arm4 along z-axis;
	wait-for-move arm5 along z-axis;
	}


BoomReset()
	{
	turn turret to y-axis <0> speed <40>;
	turn magnet to x-axis <0> speed <30>;
	turn arm1 to x-axis <0> speed <30>;
	move arm2 to z-axis [0] speed [25];
	move arm3 to z-axis [0] speed [25];
	move arm4 to z-axis [0] speed [25];
	move arm5 to z-axis [0] speed [25];
	}


BoomToPad()
	{
	start-script StartDoorOpen();

	turn turret to y-axis <0> speed <50>;
	turn magnet to x-axis <0> speed <30>;
	turn arm1 to x-axis <0> speed <30>;
	move arm2 to z-axis [0] speed [30];
	move arm3 to z-axis [0] speed [30];
	move arm4 to z-axis [0] speed [30];
	move arm5 to z-axis [0] speed [30];

	wait-for-turn turret around y-axis;
	wait-for-turn arm1 around x-axis;
	wait-for-move arm2 along z-axis;
	wait-for-move arm3 along z-axis;
	wait-for-move arm4 along z-axis;
	wait-for-move arm5 along z-axis;

	turn magnet to x-axis <-30> speed <30>;
	turn arm1 to x-axis <30> speed <30>;
	wait-for-turn arm1 around x-axis;
	}

TransportDrop(unitid,position)
	{
	call-script BoomCalc(position,get GROUND_HEIGHT(position) + get UNIT_HEIGHT(unitid));
	if(boom_ok)
		{
		set BUSY to TRUE;
		call-script BoomToPad();
		move link to y-axis 0-get UNIT_HEIGHT(unitid) now;
		attach-unit unitid to link;
		call-script BoomExtend();
		drop-unit unitid;
		call-script BoomReset();
		set BUSY to FALSE;
		}
	}

Well, to sum it up:
  • Argh's announced goal of rebuilding from scratch, free of Cavedog's I.P. is very noble. It would be a very good move for Spring, and too few have taken that direction.
  • But despite his claim and numerous "GPL" mention, that is not what he did. He copied Cavedog just like everybody else.
User avatar
Snipawolf
Posts: 4357
Joined: 12 Dec 2005, 01:49

Post by Snipawolf »

Wow, thats amazing jackalope :roll:

Jackass ...

Could a mod prove useful and delete his post?

So, how do we tell it that piecenum can be different? I don't know how to change it...

Just?

QueryNanoPiece(XXX)
{
XXX=piecefornanostuff;
}
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Post by rattle »

Why don't you try it first.
User avatar
Snipawolf
Posts: 4357
Joined: 12 Dec 2005, 01:49

Post by Snipawolf »

I'm lazy as hell ^^

edit: yup, I'm using p or something from now on :D
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

This shows that Argh did not follow chinese room method. That is script are made from Cavedog bos.
Actually, no. The TA Design Guide uses those same names and even talks about crap like activatescr or RestoreAfterDelay without mentioning that these are optional. AFAIK I never looked at an actual Cavedog script yet I learned those conventions.
el_matarife
Posts: 933
Joined: 27 Feb 2006, 02:04

Post by el_matarife »

Pxtl wrote: Even for mod-script, the GPL is confusing. The GPL was meant to cover interlinking code modules, where the GPL covers the whole system, and the LGPL covers individual modules... however, it becomes bizarre when the connection between the modules _isn't_ a direct library call - at that point, the GPL magically no longer "infects" the other code. This ambiguity makes the GPL really freaking confusing for scripts.
Additionally, you can't really make a "binary" mod. Anyone with a zip program can open it and modify it, which is the right the GPL was designed to protect. I guess you could argue that by not GPLing this content you restrict distribution, but I can't really see that as being more than a weak argument considering no one charges for this stuff and it is mirrored all over.

A good analogy is that mods for Spring are more like a spreadsheet in OpenOffice Calc, or even a program in Java/Ruby/Python etc than a standalone game. They're more content used or run by a program. The environment or application license isn't viral to the content in those cases, and I don't see why it would be viral in this case either.

Seriously, unless you are seriously creeped out by the idea of someone using your content in a commercial application or claiming credit for it or something like that, don't bother with going overboard on licensing.

(By the way, could you guys stop breaking the tables? I have to open this stuff in Opera so I can fit it all on one page without scrolling left and right.)
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post by Tobi »

Actually, while the Spring license (GPL) would never leak onto mods (since mods are just datafiles for Spring), I'm pretty sure a single mod can be considered a binary and a single work, in which case GPL'ing one file of it effectively means GPL'ing the entire mod, and also means any mod that wants to reuse part of it will either need to be GPL too, or the author will have to ask explicit permission to the original author use a particular piece of content under a different license.

The fact that you can grab 7zip or winzip, scriptor and upspring and look inside the mod doesn't change that. If that were so, then .NET programs wouldn't be GPLable either because you can just grab reflector and deassemble them. The fact that it's easy to get at the content (or source) of a binary blob of data doesn't change the copyright status at all. It just increases the risk someone who doesn't care about the license steals it.

And yeah you're right about the restriction of distribution. If you GPL your mod you can be sure the mod and all derivative works of it can be redistributed/modified by anyone as much as they like, as long as this derivative works are all GPL too. If you do not include a license, then technically no one may use (not even redistribute I think) you mod. Though I think you can not realistically claim that your mod may not be redistributed if you already uploaded it to UF or FU :P
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

I think when you upload stuff to UF you implicitely give UF a license for distribution. Also any form of saying "you can do this" is a lincense and actually binding.
User avatar
1v0ry_k1ng
Posts: 4656
Joined: 10 Mar 2006, 10:24

Post by 1v0ry_k1ng »

User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

What a terrible flash vid. That's about only 1/5 of the true length of long cat.. And I've done longer posts.








KDR_11k wrote:Actually, no. The TA Design Guide uses those same names and even talks about crap like activatescr or RestoreAfterDelay without mentioning that these are optional. AFAIK I never looked at an actual Cavedog script yet I learned those conventions.
Yeah, the TA Design Guide isn't perfect in that aspect. It forgets a few functions names that do the interface between the engine and the script (so whose name can't be guessed and have to be kept), and it talks about some function that are purely within script (so which can be renamed or even removed and have their content coded in another way).


Which reminds me in my previous post I forgot to mention that not only the name "RestoreAfterDelay();" can be changed, but the whole deal of having "start-script RestoreAfterDelay();" right after the aiming returns can be removed and coded otherwise.

For instance, once I've scripted the "turning guns back to resting position" into an everlooping function started in the "Create", which communicate with the aiming function with some static variable, basically the everlooping function use that static var as a timer, and when that timer is not null, it decrements it, and if by decrementing it it becomes <0, then it plays the resting animation. And inside the aiming function, I just put some high values in that timer. This approach is more complex, but allows different weapons to share the same turret or opening animation.


Yet another way, is to have the contents of the "RestoreAfterDelay" placed inside the "FireWeaponX", and to protect the "FireWeaponX" with the signal things. This approach is no more complex than the usual "RestoreAfterDelay()" function deal, even a tad simpler. But it has the drawbacks of eating one signal (in TA signals are limited to 8), and the drawback of not turning turret back to rest position turret when the engine decided it doesn't want to fire after all after having aimed. But it has the advantage of having one less function running at once (in TA things fall aparts when two many functions of a script are running at once).

Tobi wrote:The fact that you can grab 7zip or winzip, scriptor and upspring and look inside the mod doesn't change that.
Scriptor dessasembling function only works with simple, traditionnal, Cavedoggy scripts. If you try to uncompile a script with some real, lenghty, programming, then you end up with somehting that compile into the same (actually, not even, but that's just cause Scriptor is broken, with a better decompiler it would), but yet is unreadable and unusable, because all the comments, variable names, macros, etc... are lost.

It's just like TotalA.exe, technically you can desassemble totala.exe into a source that would compile into the same binary, but it aren't as good as the genuine source code.

But anyway it seems nowadays people just leave the bos in the archive, which is all good and well.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

Some of your "different ways to implement it" are so complex you wouldn't use them unless you had to work around a patent...

Realistic differences are e.g. the original Kernel opening script compared to a more normal implementation like having the animation in the Activate function.
User avatar
Snipawolf
Posts: 4357
Joined: 12 Dec 2005, 01:49

Post by Snipawolf »

tbh, I don't use restore after delays on my tanks..

I have a random look-around script (god bless whoever said the battlefield looked dead, it gave me inspiration to make it) and after its done lookin around, it will return to normal aiming position.

Yes, I have learned everything second hand, I've never seen an original TA script... I didn't know we could use some of these alternatives...

Whee, less TA stuff then... :P
User avatar
Zpock
Posts: 1218
Joined: 16 Sep 2004, 23:20

Post by Zpock »

You guys who go to lengths at trying to "stay legal", doing silly things like avoiding to read cavedog scripts (or lie and just say you do so), rewrite nice clear code into a garbled unreadable inneficient mess just so it looks different, and all that kind of stuff.... will you try to actually defend yourself in court against someone with money to hire lawyers (wich you will end up having to pay after loosing) should they actually decide to go after your asses? And therefore you do this as preparation... Or is it more that you believe this helps you with staying under the radar in the first place?
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

If someone sues you over something you haven't done, what else can you do except fight it out? Not fighting means losing by default and I'm not sure killing their CEO with an RPG is going to work either.
User avatar
Zpock
Posts: 1218
Joined: 16 Sep 2004, 23:20

Post by Zpock »

KDR_11k wrote:If someone sues you over something you haven't done, what else can you do except fight it out? Not fighting means losing by default and I'm not sure killing their CEO with an RPG is going to work either.
You receiva a CaD from some corporate scum with hordes of blodsucking lawyers, your options are:

A: Fighting and loosing means you pay their legal expenses + damages and have to give in to their demands.

B: Not fighting, giving in to their demands straight away, you only have to give in to their demands.

Simple, They can afford fighting (and loosing), you can't.
User avatar
Neddie
Community Lead
Posts: 9406
Joined: 10 Apr 2006, 05:05

Post by Neddie »

C: Fight and win, due to enormous luck.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

You don't automatically pay their legal expenses.
Locked

Return to “Game Development”