Cyclic Animation for Newbies - Page 3

Cyclic Animation for Newbies

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
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

What do you mean? "expand the <>s" doesn't tell me what you're looking at.
tombom
Posts: 1933
Joined: 18 Dec 2005, 20:21

Post by tombom »

Argh wrote:What do you mean? "expand the <>s" doesn't tell me what you're looking at.
Instead of doing <2> and having Scriptor multiply it by a constant or whatever, you put the result in. Like instead of <2> you have 32000 or whatever.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Oh. Basically, I was just talking about what the final, compiled code looks like. What I was trying to get at was that:

1. You want as little pushed / fetched as possible
2. You want as few math steps as possible

So, "turn Part to x-axis <W> * X speed <Y> * Z" is a very stupid way to write code, because even if you're using local-vars in that expression, it's lousy with extra math steps.

However, when doing an initial setup, it's nice to do something like:

Code: Select all

TestMe(Myspeed)
{
Myspeed = 5;
if(bMoving)
{
turn Part to x-axis <45> speed <15> * Myspeed;
}
}
Just for ease of maintenance. Because you can always just go back with your calculator and manually remove the * speed later on, once you have tested the animation in Spring to make sure that it fits the gameplay you have in mind. All of the numbers will get converted to integers by the compiler.

What KDR is rightly pointing out is that if you maintain a bunch of things that all share the same Piece names, you could save a bunch of time by using #includes, so that everything shared a common codebase and did not have to be re-written from scratch. Which is great, if I was doing all human walkscripts, and I'll probably adapt that to my human walkscript that is shared in common with a lot of stuff in the game, actually. It's a good idea, if you have 10 things that are all basically the same, with minor differences. More work than it's worth, though, if you are talking about 10 different things with dis-similar setups, imo.
Last edited by Argh on 04 Jun 2007, 01:35, edited 1 time in total.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

I've tested KDR's approach, and I ran into a giant, ugly problem: there's no way to prevent speeds from being returned as negative numbers, which always causes Spring to take the longest possible distance. This is not a problem, if you're content with a two-position walkscript, but it becomes a giant pain in the butt very quickly, as you see more and more areas where a single math error ruins your script.

There seems to be no way around this, that I can see, because everything in a #define needs to be a non-logic step- it doesn't understand if() statements, which is a necessary step here, because we have to evaluate the results, and there aren't any handy C/C++ operators like unsigned-ints that can prevent this.

So, if anybody has some way to evaluate the contents of a #define and preclude negative speeds being introduced, I'd like to hear about it- the only ways that I can see doing this include really ugly hack-arounds that are ultimately less-efficient than what I was doing previously.
User avatar
TheRegisteredOne
Posts: 398
Joined: 10 Dec 2005, 21:39

Post by TheRegisteredOne »

All of the numbers will get converted to integers by the compiler.
I don't think the compiler does that, "Myspeed" is a variable, it can change through the execution of the script, (you can pass in 5, 3, or anything into "Myspeed"), thus i think the compiler will leave something like "<15> * Myspeed; " in
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Yup, you're right, if you leave it as MySpeed, sorry that wasn't at all clear.

If you #define MySpeed, then it gets turned into a literal. If you var MySpeed, it is treated much like a static-var, but it doesn't go outside the script loop looking for it, and will pick up the value again during the pass through the script... or never again, if defined before the While(TRUE), if I'm reading the output right.

However, that still leaves a multiplier step in there, so it's not, theoretically-speaking, very efficient. Having tested that tonight in a practical sense, though... so far as I can tell, that works quite a bit more efficiently than the previous way I was doing this, where I was using static-vars, and I'm rather tempted to just use this everywhere, because it makes writing a script so easy. I can always come back later and clean it up for pure optimization purposes later on, when I don't have five billion other things that need doing.
User avatar
TheRegisteredOne
Posts: 398
Joined: 10 Dec 2005, 21:39

Post by TheRegisteredOne »

it is still the script that does the calculations, not the compiler. if you define "Myspeed" as 2, and compile "<30> * Myspeed", the compiler converts that to "<30> * 2" and that's it. you can try it. when you decompile the resulting cob, you get something like "<30> * <0.010989>", which is basically "<30> * 2".
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Post by rattle »

Try to turn "make large numbers in into linear constants" off when decompiling.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

Um, what do you have to do to cause negative speeds?

Also precompiler statements are pretty useful for code that gets reused with small variations, even if those variations are the number of variables used.

Example, an ammo 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()
{
	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=get 70;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;
                }
			}
		}
	}
}
I can use that script for one ammo type by #defining only MAX_AMMO, I can use it for two weapons with #define MAX_SECONDARY_AMMO and I can use a custom condition to determine when a refill is needed by #defining CUSTOM_CONDITION to be what I need. Might be useful for the Advance Wars mod, they could use fuel through the same system.

Example use for a unit that will change its weapon according to its activation status upon refill:

Code: Select all

RefillAmmo()
{
	hide ammosymbol;
	weapontype = get ACTIVATION;
	if (weapontype) {
		hide rifle;
		show missilelauncher;
	}
	else {
		show rifle;
		hide missilelauncher;
	}
}

#define MAX_AMMO 50
#define CUSTOM_CONDITION ammunition < MAX_AMMO || weapontype != get ACTIVATION
#include "ammunition.h"
(all code in this post available for free use)
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Post by rattle »

Um, what do you have to do to cause negative speeds?
What speed? Unit speed can't be negative.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

Rotation speed.

If they ever are negative, it turns the wrong way around.
Post Reply

Return to “Game Development”