Page 1 of 1
Scripting help
Posted: 04 Dec 2006, 15:21
by Maelstrom
Is there a way to get the rotation of a peice in the unit your scripting? Its probably something really simple, but how do you do it?
Re: Scripting help
Posted: 04 Dec 2006, 16:50
by zwzsg
The only way I know is indirect, only works if the rotation is around the Y axis, etc... but it goes like this: To know the rotation of pieceA, make a new piece, pieceB, child of pieceA, and move it (in 3doBuilder/UpSpring) in front of pieceA. Then in the script when you need to know how much pieceA turned around the Y axis, do:
get XZ_ATAN(get PIECE_XZ(pieceA) - get PIECE_XZ(pieceB))
pieceA must not be turned on other axis than Y, and all the ancestors of pieceA must not turn at all, I don't know if it works while the unit is tilted by the ground slope, etc...
Using get ATAN and get PIECE_Y you can probably find how much the unit turned around X, or Z, in a similar way. Just don't try to combine rotations.
Posted: 04 Dec 2006, 16:53
by Maelstrom
Sweet, this will work great. Its only turning round the Y axis, so this should work fine. Ill give it a go.
Posted: 04 Dec 2006, 17:35
by Maelstrom
Nope, im doing something wrong. What could be wrong with the following script? Its called via start-script in Create():
Code: Select all
while (TRUE)
{
gun_rotation = get XZ_ATAN(get PIECE_XZ(platform) - get PIECE_XZ(rotate_piece));
turn cog_right to x-axis gun_rotation * COG_TURN now;
turn cog_left to x-axis gun_rotation * (0 - COG_TURN) now;
sleep 10;
}
The cogs only turn a few times a second. Ive tried various sleep values, and they dont change much, its still laggy even with a sleep 1.
Posted: 04 Dec 2006, 18:05
by KDR_11k
I figured you were using secondary turrets but your problem there can be solved by using start-spin on the cogs, wait-for-turn on the turret and stop-spin on the cogs after that.
Code: Select all
TurnTurret(angle) {
signal SIG_Turn;
set-signal-mask SIG_Turn;
gun_rotation = get XZ_ATAN(get PIECE_XZ(platform) - get PIECE_XZ(rotate_piece));
if (gun_rotation > angle) { //will probably have to be more complex to work right, didn't feel like thinking through the whole formula
start-spin cog_left around x-axis speed ---;
start-spin cog_right around x-axis speed ---;
} else {
start-spin cog_left around x-axis speed +++;
start-spin cog_right around x-axis speed +++;
}
turn platform to y-axis angle speed ---;
wait-for-turn platform around y-axis;
stop-spin cog_left around x-axis;
stop-spin cog_right around x-axis;
}
Posted: 04 Dec 2006, 19:36
by rattle
Uh tried using a speed instead of now?
Posted: 04 Dec 2006, 20:47
by Argh
I use this on all objects with restricted-arc aiming. Might be handy. Basically, you just need to "decide" if it's turning right or left. Added lines for the gears.
Code: Select all
signal SIG_AIM1;
set-signal-mask SIG_AIM1;
pitch_01 = pitch;
IF ( pitch_01 <= 32768 )
{
turn gun_aimer to x-axis 0 - pitch speed <200.0>;
}
IF ( pitch_01 > 32768 )
{
turn gun_aimer to x-axis pitch speed <200.0>;
}
heading_01 = heading;
IF ( heading_01 <= 32768 )
{
turn turret to y-axis heading speed <200.0>;
spin gear1 around x-axis speed <50>;
spin gear2 around x-axis speed <-50>;
}
IF ( heading_01 > 32768 )
{
turn turret to y-axis 0 - heading speed <200.0>;
spin gear1 around x-axis speed <-50>;
spin gear2 around x-axis speed <50>;
}
The big problem with this approach is that:
A. Getting the exact, perfect ratio at which the gears will precisely match the lower gear and never slip is going to be extremely hard.
B. It may, in fact, be impossible. There is an absolute limitation on how fine of a control one can achieve in turning.
Posted: 05 Dec 2006, 11:37
by Maelstrom
Now I have two problems
Your ideas unfortunately did not work. They still made the cogs jump like before. So theres still that problem
Another problem, the maths I did to work out how to turn the cogs SHOULD work (
I even made a program to test it), but once I put it in Spring, it starts not working. The cogs dont quite turn at the right speed, its just slightly off. I used the following code to test it:
(COG_TURN is 2.5, as I worked out from my program)
Code: Select all
CogTurn()
{
while (TRUE)
{
gun_rotation = gun_rotation + 10;
turn platform to y-axis gun_rotation now;
turn cog_right to x-axis gun_rotation * COG_TURN + gun_rotation now;
turn cog_left to x-axis gun_rotation * (0 - COG_TURN) - gun_rotation now;
sleep 10;
}
}
Create()
{
start-script CogTurn();
}
The equivelant of this code works with that program I made, yet it doesnt work in Spring. Any ideas why?
EDIT:
Here is the unit im building this script for, if anyone is curious
Re: Scripting help
Posted: 05 Dec 2006, 14:37
by zwzsg
What's that "COG_TURN" constant? Why can't it be one (I mean not be here)? Oh nevermind you said it's 2.5 below. Well, 2.5 is of same scale as 1 so it's fine... uh.. hey do you know that 2.5 will get floored to 2? The only variable handled by script are 32 bits signed integer. Any fractionnal gets floored to nearest lower integer.
Last time I tried "else" did not work in Scriptor v1.0 RC1. Maybe it would compile but the "else" part would get executed no matter the condition. Are you using another compiler? Have you checked that ingame the part after the "else" really get exectuted only if the part after the "if" isn't?
"if (gun_rotation > angle)" It sounds wrong to me to do that before checking the angles are in the proper interval to be compared. What I mean is that if you count angle on the 0° 360° interval, then 355° > 10°, while in reality 355° should be -5° so < 10°. If insted you use the -180° +180° interval, then -175° < 170°, while in reality -175° is 185° so it shoudl be 185°>170°. Hmm, not sure I'm clear here. Ok, let's say gun_rotation is 350° and angle is 10°, would say that 350° > 10°, or would you understand that 350° = -10° and that -10°< 10° ? Well maybe you are certain of which range the value returned by "get XZ_ATAN" and the value passed into TurnTurret argument are, and are certain they're in interval that allows them to be compared. Or more probably you didn't think about it but are lucky enough that they were.
Otherwise I don't understand very well the purpose of the second script bit, so can't say.
Then come a script bit that start some spinning when the turret has to turn more than 180° (Is it Spring or TA which use the -180° 180° range for the 'heading' & 'pitch" argument while the other use 0 360°?), not sure what it has to do with the topic at hand.
"gun_rotation * (0 - 2.5) - gun_rotation"
can be simplified into:
"-3*gun_rotation"
I don't understand very well either what's the point.
Oh well maybe I should refrain from replying until I get a clue.
I could say that I know using get XZ_ATAN to find out the current angle of a piece works as I used it on
the new monkeylord walkscript for legs to stop turning when they're the same angle as the leg behind, and it worked fine on flat ground. But that's not going to help you.
Posted: 05 Dec 2006, 14:49
by Maelstrom
uh.. hey do you know that 2.5 will get floored to 2? The only variable handled by script are 32 bits signed integer. Any fractionnal gets floored to nearest lower integer.
THAT would explain my problem! Damn, i didnt even think of that one. Ok, i will remodel the cogs to have 10 teeth, then COG_TURN can be set to 2 safely. Thanks for the hint.
And I have no doubt the XZ_ATAN bit works, your the uber-scripter here, I was guessing it was my implementation of it that was the problem.
Posted: 05 Dec 2006, 17:20
by zwzsg
Ok, i will remodel the cogs to have 10 teeth, then COG_TURN can be set to 2 safely. Thanks for the hint.
There is another way, it is to ensure that every time you write a formula, you do all the multiplication first and all the division last (Unless you risk hitting the 2147483647 limit).
So, instead of:
turn cog_left to x-axis gun_rotation * (0 - 2.5) now;
Use:
turn cog_left to x-axis -5*(gun_rotation)/2 now;
(because 0 - 2.5 = -5/2)
Re: Scripting help
Posted: 05 Dec 2006, 18:03
by KDR_11k
zwzsg wrote:Last time I tried "else" did not work in Scriptor v1.0 RC1. Maybe it would compile but the "else" part would get executed no matter the condition. Are you using another compiler? Have you checked that ingame the part after the "else" really get exectuted only if the part after the "if" isn't?
I'm pretty sure "else" works. I have loads of scripts that rely on it and they work as intended. Maybe your installation is corrupt?
zwzsg wrote:"if (gun_rotation > angle)" It sounds wrong to me to do that before checking the angles are in the proper interval to be compared.
I know, that's why I put the comment behind it that I'm too lazy to work out the correct formula. He can do some thinking for himself

.
Posted: 05 Dec 2006, 18:13
by FLOZi
I'm pretty sure my version of scriptor won't even compile 'else' statements

Posted: 05 Dec 2006, 18:28
by rattle
I'm pretty sure it supports the else statement, I use it wherever I can to ease things up, there's no elseif though. Also #else is supported.
It's a shame it doesn't have simple stuff like switch which would making clear scripts so much easier however...
Posted: 06 Dec 2006, 10:50
by zwzsg
Now that I had a look at the model, I understand what you're trying to do. And I'm appalled. You're doing it wrong! Basically what you're trying to do is the equivalent of using a F15 to kill a dead fly. It's wrong because:
- You don't have to kill the fly as it's already dead. Just extend your arm to grab the fly corpse.
- You risk accidentally blowing up your house, or the neighbour house.
- Only well trained pilot can use F15.
- Such craft need never ending maintenance and care to work.
- Those guided or heat seeking missiles are very expensive.
- The flat side of your hand is a good enough weapon to squish a fly.
Enough with the silly metaphor. What I mean is that you don't need to retrieve the angle of a piece, you don't need to use "get XZ_ATAN", you don't need an ever looping function that check the gun angle and turn the cob accordingly, etc.. I can be made alot more simple and efficient:
Every time you turn the turret:
turn turret to y-axis <123> speed <456>;
turn the little cobs as well:
turn cobleft to x-axis (<123>)*N2/N1 speed (<456>)*N2/N1;
turn cobright to x-axis 0 - (<123>)*N2/N1 speed (<456>)*N2/N1;
So your script would be like:
Code: Select all
#define SIG_AIM1 2 // any power of 2 not already used by another signal and I think you're limited to 8 bits so don't go over 128
#define NBR_TEETH_BIG_COG 15 // I didn't bother actually counting them, so change to the actual number
#define NBR_TEETH_SMALL_COG 6 // I didn't bother actually counting them, so change to the actual number
TargetCleared(k)//Rare TA function, I'm not even sure Spring calls it, and anyway you don't really need it.
{
// Stop the turret rotation when the target is no more
stop-spin gun around x-axis;
stop-spin turret around y-axis;
stop-spin cobleft around x-axis;
stop-spin cobright around x-axis;
}
RestoreRestPosition()// Usually not used on immobile turrets
{
sleep 5000;//Or a time proportionnal to the first argument of SetMaxReloadTime as usual
turn gun to x-axis 0 - <30> speed <40>;// would look better if default resting position wasn't perfectly horizontal but aimed a bit upward. Sadly I don't remember if I must use negative or positive to aim up, so remove the 0 - if it nose dive when resting. Oh and "turn ... now" the same in Create()
turn turret to y-axis 0 speed <20>;
turn cobleft to x-axis 0 speed (<20>)*(NBR_TEETH_BIG_COG)/(NBR_TEETH_SMALL_COG);
turn cobright to x-axis 0 speed (<20>)*(NBR_TEETH_BIG_COG)/(NBR_TEETH_SMALL_COG);
}
AimFromPrimary(p)
{
p=0;//Just don't use a piece that is moved when the turret turns
}
AimPrimary(heading,pitch)
{
signal SIG_AIM1;//Kill any previous instance of AimPrimary
set-signal-mask SIG_AIM1;//Make it killable
turn gun to x-axis 0 - pitch speed <70>;
turn turret to y-axis heading speed <50>;
turn cobleft to x-axis heading*(NBR_TEETH_BIG_COG)/(NBR_TEETH_SMALL_COG) speed (<50>)*(NBR_TEETH_BIG_COG)/(NBR_TEETH_SMALL_COG);
turn cobright to x-axis 0 - ((heading*(NBR_TEETH_BIG_COG))/(NBR_TEETH_SMALL_COG)) speed (<50>)*(NBR_TEETH_BIG_COG)/(NBR_TEETH_SMALL_COG);
wait-for-turn turret around y-axis;
// No need to wait for the little cobs, they'll arrive exactly in the same time as the turret.
wait-for-turn gun around x-axis;
start-script RestoreRestPosition();// Static building usually don't restore their position to aiming south, they keep their last aiming angle to be ready for next attack, so you'd better not use that line
return(1);
}
QueryPrimary(p)
{
p=flare;
}
There's a 50% probability that I inverted left and right. All typed in notepad, without testing, so I hope there's not too many syntax errors. If I did so, well, just switch the piece names. You probably don't want to use the TargetCleared and RestoreRestPosition, I just typed them to show other exemple of turning all three pieces at once in the same script.
Posted: 06 Dec 2006, 11:50
by Maelstrom
Thanks yet again.
I had tried something similar to that, but because of the 2.5, it didnt work. Not that it would have probably worked anyways, but the whole angle thing wasnt my first try. Those other ideas came from desperation.
Ill chuck it in my script and see if it works.