Sign in to follow this  
Followers 0

another problem: move point a distance at arbitrary angle in acs

EDIT: solved this one too
NEW PROBLEM:
trying to move a point (x & y) a arbitrary distance at an arbitrary angle. Too much fixed point vs map point, radians vs deg, byte angle vs blah angle...
Don't even think the cosine is spitting out the right thing because google gave me cos(45) is 0.52532198881... but acs was telling me it was about 0.7 or so I think.

function int moveByAngle(int startx, int starty, int distance, int angle)
{
    //print(f: cos(angle<<8));
    //int startx = -3296, starty = 2080, distance = 88, angle = 32;
    movedPoint[0] = startx + (cos(angle<<8) * distance);
    movedPoint[1] = starty + (sin(angle<<8) * distance);
    return 0;
}
I think <<8 was needed to make the byte angle a fixed point angle.
Supposedly cos(angle<<8) should return a fixed point number but trying to >>16 or <<16 or whatever it didn't seem to work.
Basically the above is probably full of fail and I'm doing it wrong.



----------
EDIT: BELOW WAS SOLVED/IGNORE figured the below out, so ignore it. I had to type compat_nopassover = "false" in the console. Apparently it has been set to true all this time, don't remember why.
--

So I guess you can't spawn monsters on top of eachother? This is weird because this is zdoom doom in hexen, and it at least spawned a flat plane of 8x8 pain elementals (even though I wanted a 8x8x8 cube which spawn failed to make). But even though the plane was 256 high, I couldn't walk underneath them... I thought zdoom had no infinite tallness doubleyou tee eff.

The 2nd column part prints z each time, so you can see z is correct but it just doesn't spawn anymore when a monster has already been spawned exactly below it.
#include "zcommon.acs"

script 1 open
{
    //tried to spawn 8x8x8 cube of pain elementals, but it only spawned 1 flat 8x8 2d plane

    int x,y,z;
    int xoffset = -2976;
    int yoffset = 1568;
    int zoffset = 256;
    int spacing = 88;
    int tid = 1;
    for(z=0;z<8;z++)
    {
        for(y=0;y>-8;y--)
        {
            for(x=0;x<8;x++)
            {
                spawn("painelemental",(xoffset+(x*spacing))<<16, (yoffset+(y*spacing))<<16, (zoffset+(z*spacing))<<16, tid, 192);
                //print(d:(zoffset+(z*spacing)));
                tid++;
            }
        }
    }
    
    //tried to spawn a column, only spawned a single
    
    int myTid = 2000;
    for(z=0;z<8;z++)
    {
        delay(100);
        spawn("painelemental",(-2976-256)<<16, 1568<<16, (zoffset+(z*spacing))<<16, myTid, 192);
        myTid+=1;
        print(d: zoffset+(z*spacing));
        delay(5);
    }
}

Share this post


Link to post

Ha ha, the youtube in that link was cool. I figured my problem out though, so its yet another useless thread from me. I had to set compat_nopassover to false.

Share this post


Link to post

bump for new problem, edited op

Share this post


Link to post
gggmork said:

NEW PROBLEM:
trying to move a point (x & y) a arbitrary distance at an arbitrary angle. Too much fixed point vs map point, radians vs deg, byte angle vs blah angle...
Don't even think the cosine is spitting out the right thing because google gave me cos(45) is 0.52532198881... but acs was telling me it was about 0.7 or so I think.

well google is right. and acs cos() is also right, because its docs say it takes a fixed point angle!1

gggmork said:

function int moveByAngle(int startx, int starty, int distance, int angle)
{
    //print(f: cos(angle<<8));
    //int startx = -3296, starty = 2080, distance = 88, angle = 32;
    movedPoint[0] = startx + (cos(angle<<8) * distance);
    movedPoint[1] = starty + (sin(angle<<8) * distance);
    return 0;
}

Looks correct to me. It takes byte angles though, is that what you want?

Share this post


Link to post

Yes, I want to feed it a byte angle. But <<8 converts it to fixedpoint angle. I solved my problem though:

crikey, I finally figured out the maze of subtle cryptic hurdles.
First of all, google gave me cosine of 45 RADIANS, googled again for 45 DEGREES and that matched acs's output.

But that wasn't even the problem that was mostly confusing me. Turns out:
startx + (cos(angle<<8) * distance);
the above had startx set to 64 but it wasn't adding on correctly, I guess because it was an integer instead of floating point. Turns out I can't use 64, but have to write 64.0, then it works...
(tried doing 64<<16 or 64>>16 since that always confuses me, but just using 64.0 made it add properly.

Share this post


Link to post

<< makes things bigger, and >> makes things smaller. Think of them as arrows. They move the value around, which is the same as multiplying or dividing by a power of two.

0001 0100 << 3 = 1010 0000
0001 0100 >> 3 = 0000 0010

Share this post


Link to post

That makes sense, python never taught me to think at the bits/bytes level. So print(d:32<<1); prints 64 etc.

I assume doing:
32<<16
doesn't automatically "convert" it to fixed point.. its really treated just like a huge integer.. unless a particular function is specifically set up to handle it like fixed point.

For example I had 64 which didn't add properly (mentioned in a previous post) whereas 64.0 did. But 64<<16 didn't "equal" 64.0 even though it seems like it should because <<16 makes it fixed point format.

Also I guess you can't use decimal points in for loops? This prints "21.6" one time then the loop dies, instead of printing 1.2...etc as expected:

script 2 open
{
    //prints 21.6 one time
    int i;
    for(i=1.2;i<20.0;i+=1.7);
    {
        delay(100);
        print(f:i);
    }
}
None of these prints 70.. I guess the only way is to "cast" a 6 into a 6.0 by multiplying by 1.0 or something, since apparently both have to be decimals in order to add?:
script 2 open
{
    //prints 64.0001
    delay(100);
    print(f: 64.0 + 6);
    
    //prints 0.000976562
    delay(100);
    print(f: 64.0 + 6>>16);
    
    //prints 6
    delay(100);
    print(f: 64.0 + 6<<16);
    
    //prints 4194310
    delay(100);
    print(d: 64.0 + 6);
    
    //prints 64
    delay(100);
    print(d: 64.0 + 6>>16);
    
    //prints 393216
    delay(100);
    print(d: 64.0 + 6<<16);
}

Share this post


Link to post

In C at least, precedence of << and >> is lower than precedence of +, and apparently in ACS too. That is, compiler interprets

64.0 + 6<<16
as
(64.0 + 6)<<16
Put in parentheses like this:
64.0 + (6<<16)
====================================================

apparently both have to be decimals in order to add?:

Of course! 1.0 is really 65536. So when you write

1.0 + 65536
it is really 65536+65536, which is 131072, or 2.0.
As for the "for" loop, waiting for Gez to explain. So far it looks like a bug...I should pay more attention

Share this post


Link to post

That makes sense and those parenthesis did indeed fix it. Thanks.
Wondering about decimal points in for loops too. I could work around and put them all in an array or something if necessary I guess. Or count with integers and have a separate decimal ++ whatever each iteration.

Share this post


Link to post
gggmork said:

Wondering about decimal points in for loops too. I could work around and put them all in an array or something if necessary I guess. Or count with integers and have a separate decimal ++ whatever each iteration.

I recommend you to go to zdoom forums and ask there. Perharps they will fix that, or tell you what's wrong with your script.
Also, may I use this opportunity to remind you that 0.1+0.1 is not 0.2 in fixed point, and using ++ increments by 1 and not 1.0.

Share this post


Link to post
gggmork said:

I assume doing:
32<<16
doesn't automatically "convert" it to fixed point.. its really treated just like a huge integer..

Fixed point and huge integers are basically the same thing. There is no difference internally.

An integer like 57 is also a very tiny value in fixed point.

gggmork said:

Also I guess you can't use decimal points in for loops? This prints "21.6" one time then the loop dies, instead of printing 1.2...etc as expected:

script 2 open
{
    //prints 21.6 one time
    int i;
    for(i=1.2;i<20.0;i+=1.7);
    {
        delay(100);
        print(f:i);
    }
}

Your problem is that you have a semi-colon after the for condition. So the loop is done on an empty expression, and the code in curly brackets is run only once after the for loop is finished.

If you remove that semi-colon, it should work. I see no reason for it not to work.

tempun said:

Also, may I use this opportunity to remind you that 0.1+0.1 is not 0.2 in fixed point


Huh?

6553+6553=131106 = 0.199981689453125, so it should be rounded to 0.2 I think.

Share this post


Link to post
Gez said:

Your problem is that you have a semi-colon after the for condition.


Ha ha, I'll go put on my dunce hat.

Share this post


Link to post
Gez said:

Huh?

6553+6553=13106 = 0.199981689453125, so it should be rounded to 0.2 I think.

FTFY
And 0.2 is represented as 13107, no?
Rounded? Does ZDoom's ACS interpreter somehow identify fixed-point number and perform DECIMAL rounding at them? I'm confused.

Share this post


Link to post

The print(f:var) function does IIRC. It converts the value to an actual floating point number and uses plain C function to turn that into a string.

		case PCD_PRINTFIXED:
			work.AppendFormat ("%g", FIXED2FLOAT(STACK(1)));
			--sp;
			break;

Share this post


Link to post
Gez said:

The print(f:var) function does IIRC. It converts the value to an actual floating point number and uses plain C function to turn that into a string.[/code]

But that's rounding to six significant digits, enough to make it not round to 0.2.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0