I'm afraid I don't completely understand how parts of it are supposed to work, but I fixed a couple of problems.
Code:
if (state ==0){
if (this->X >= x_origin + 32){ state = 1; }
else{
this->Vx = Sin( ( 2 * pi) / 32) * (this->X - x_origin);
}
if (i >= wait) { i = 0; state = 2;}
else{ i = i + 1;}
}
x_origin is initialized to this->X, so you're multplying that sine by 0.
I think you may want to skip the velocity and modify the position directly, something like this->X = x_origin + 32 * Sin(i). That should also eliminate the need for separate left and right motion states. But that's the part of the script where I'm least certain of your intent, so that might not be quite what you want.
If not...
Code:
if (this->X >= x_origin - 32){ state = 0; }
Make sure, at least, to change that to this->X <= x_origin - 32.
Code:
if (state ==2){
x_target = Link->X;
y_target = Link->Y;
if ( i >= delay ){ i = 0; state = 3; }
else {
this -> Vx = 0;
this->Vy = -0.1;
}
}
Don't forget to increment i.
Code:
if (state == 3){
if ( (this->X >= x_target - 16) && (this->X <= x_target + 16) &&
(this->Y >= y_target - 16) && (this->Y <= y_target + 16) ){
state = 4;
}
else{
dist = distancesq(x_target, this->X, y_target, this->Y);
x = this->X;
y = this->Y;
this->Vx = 2* ((x_target - x)*Abs((x_target - x))/dist);
this->Vy = 2 * ((y_target - y)*Abs((y_target - y))/dist);
}
}
Do you mean to be using both target-16 and target+16? The target was set to Link's top-left corner, so the end area defined in the if statement is a 2x2 tile square with Link's original position in the bottom-right.
Remember to set the velocity back to 0 after it hits.
Also, though you don't really have to set i to 0, since it was already 0 and wasn't changed, it would just make a bit more sense to set it here than at the end of state 2.
Code:
if (state == 4){
if ( i >= delay/2 ) { i = 0; state = 5;}
else{ i = i++; }
}
Not sure if you don't know or if you just mistyped it, but i = i++ is redundant. It's just i++ instead.
I doubt that would cause any problems, but it's not inconceivable.
Code:
if (state == 5){
if ( (this->X >= x_origin - 16) && (this->X <= x_origin + 16) && (this->Y >= y_origin - 16) && (this->Y <= y_origin + 16) ){
state = 0;
}
else{
dist = distancesq(x_origin, this->X, y_origin, this->Y);
x = this->X;
y = this->Y;
this->Vx = ((x_origin - x)*Abs((x_origin - x))/dist);
this->Vy = ((x_origin - y)*Abs((x_origin - y))/dist);
}
}
Again, remember to reset i and the velocities to 0.
Gah, it's after four in the morning. It doesn't seem to be right yet, but I can't keep working on it now. Hopefully I didn't screw anything up too badly, at least.
Here's the script with all the above changes, whether you wanted them or not...
Code:
import "std.zh"
int distancesq(int x1, int x2, int y1, int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
// ===============================================
// TAIL_WHIP : This ffc will move slowly back and forth horizontally
// over four tiles, centered on it's original location. After a set amount
// of time, it will lash out towards link' s location at a high speed. It
// will pause breifly after reaching link's old location, and then return
// to it's starting point to continue wagging. Will use FFCs 1,2, 3, 4, and 5
// as tail segments, and FFC 6 as the base of the tail. Accordingly,
// the Tail_Whip FFC should be FFC 7.
// ===============================================
ffc script tail_whip{
// CONSTANTS
int wait = 60; // How long the tail waits
float pi = 3.14; // It's pi!
int delay = 10; // How much warning Link gets before
// the tail strikes
// VARIABLES
int i = 0; // Counter
int x_origin = 0;
int y_origin = 0;
int x_target = 0;
int y_target = 0;
int x; // working variables
int y;
int dist;
int state = 0; // The state of the tail_whip.
// 0 = wagging right
// 1 = wagging left
// 2 = pulling back to strike
// 3 = striking at link
// 4 = pausing after striking
// 5 = returning to wagging mode
// RUN FUNCTION
void run(){
// POINTERS
ffc segment_1 = Screen->LoadFFC(1);
ffc segment_2 = Screen->LoadFFC(2);
ffc segment_3 = Screen->LoadFFC(3);
ffc segment_4 = Screen->LoadFFC(4);
ffc segment_5 = Screen->LoadFFC(5);
ffc base = Screen->LoadFFC(6);
x_origin = this->X;
y_origin = this->Y;
while (true){
// Wagging
if (state ==0){
this->X = x_origin + 32 * Sin(i);
if (i >= wait) { i = 0; state = 2;}
else{ i++;}
}
// State 1 no longer used
// Targeting and pulling back to strike
if (state ==2){
x_target = Link->X;
y_target = Link->Y;
if ( i >= delay ){ state = 3; }
else {
this -> Vx = 0;
this->Vy = -0.1;
i++;
}
}
if (state == 3){
if ( (this->X >= x_target) && (this->X <= x_target + 16) &&
(this->Y >= y_target) && (this->Y <= y_target + 16) ){
this->Vx = 0;
this->Vy = 0;
state = 4;
i = 0;
}
else{
dist = distancesq(x_target, this->X, y_target, this->Y);
x = this->X;
y = this->Y;
this->Vx = 2* ((x_target - x)*Abs((x_target - x))/dist);
this->Vy = 2 * ((y_target - y)*Abs((y_target - y))/dist);
}
}
if (state == 4){
if ( i >= delay/2 ) { i = 0; state = 5;}
else{ i++; }
}
if (state == 5){
if ( (this->X >= x_origin - 16) && (this->X <= x_origin + 16) && (this->Y >= y_origin - 16) && (this->Y <= y_origin + 16) ){
this->Vx = 0;
this->Vy = 0;
i = 0;
state = 0;
}
else{
dist = distancesq(x_origin, this->X, y_origin, this->Y);
x = this->X;
y = this->Y;
this->Vx = ((x_origin - x)*Abs((x_origin - x))/dist);
this->Vy = ((x_origin - y)*Abs((x_origin - y))/dist);
}
}
// After moving the tail end, next the tail segments are moved into position.
// First, put the third segment at the midpoint.
segment_3->X = ( (this->X - base->X) / 2);
segment_3->Y= ( (this->Y - base->Y) / 2);
// Next, place the other segments by finding the midpoint between 3 and the
// base, and between 3 and the tail whip, and placing two segments
// around it.
x = ( (segment_3->X - base->X) / 2);
y = ( (segment_3->Y - base->Y) / 2);
segment_1->X = ( ( x - base->X) / 2);
segment_1->Y = ( ( y - base->Y) / 2);
segment_2->X = ( ( x - segment_3->X) / 2);
segment_2->Y = ( ( y - segment_3->Y) / 2);
x = ( (segment_3->X - this->X) / 2);
y = ( (segment_3->Y - this->Y) / 2);
segment_4->X = ( ( x - segment_3->X) / 2);
segment_4->Y = ( ( y - segment_3->Y) / 2);
segment_5->X = ( ( x - this->X) / 2);
segment_5->Y = ( ( y - this->Y) / 2);
Waitframe();
} // end of while loop
} // end of void run()
} // end of ffc script
One interesting thing I noticed... If I change the script thusly:
Code:
ffc segment_1 = Screen->LoadFFC(2);
ffc segment_2 = Screen->LoadFFC(3);
ffc segment_3 = Screen->LoadFFC(4);
ffc segment_4 = Screen->LoadFFC(5);
ffc segment_5 = Screen->LoadFFC(6);
ffc base = Screen->LoadFFC(7);
... And attach it to FFC #1, it works quite differently, even aside from the pieces being shifted. It's closed to how it's meant to work, I think. Perhaps I'm mistaken, but I don't think it should make any difference. I believe it might indeed be a problem in the compiler or the game itself.