• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] Position

Level 31
Joined
Jul 10, 2007
Messages
6,306
Updated to 2.0.0.0 with a new extension that does spherical coordinates =D.

Made some of the code better as well, etc... yar =P


So for spherical coordinates, imagine a sphere around a unit or w/e... the distance would be the radius of the sphere, theta would be how far around (circular), and phi would be how far up/down (vertical up down).

You learn about spherical coordinates in calculus 3, but that's the general gist.

So yea, now you guys can do some really crazy stuff o_O.

Let's say you had a unit facing 0 degrees. If you had a wisp and made its origin the unit, then it would be right at the unit. If you increased the distance to 100, it would be 100 in front of the unit. If you increased theta to pi/2, it'd be to the left of the unit 100 away. If you increased phi to pi/2 and decreased theta to 0, it'd be directly above the unit.

Have fun : D.

edit
will perform a couple of minor optimizations in a 2.0.0.1
 
Last edited:
Level 12
Joined
Mar 28, 2005
Messages
160
i still dont get it

you make all these weird things that seem to have very limited use in real world scenarios

why would I have use this for a spawn system? when I could just store my locs as needed (if needed) and use them from then on out? i don't see hwo this is any easier then just using locs directly
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I have to agree, using location is only useful with GetLocationZ, and even you don't need to create locations dynamically, just few on map initialisation (can be also created with the default value of the global variable) and then use the function MoveLocation.
Ofc you know that, so i'm really surprised you dit it.

This system seems far overkilled, i means it's only for theoric purpose, can be easily avoid with no pain at all in any real usage.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Actually, as the first post says, I initially made this for a combat system... when a target is passed around across multiple resources, that target may be anything (location, unit, destructable, item) and it may be used by many things. If it's used by many things, when do you know to destroy a location?

Furthermore, if you have a spawn, the origin of that spawn may be a location, unit, destructable or item.

Also, I disagree with how useful locations are... if you share a location across multiple systems, then you can update that location, which will properly update all of the systems. If you use x,y, then you have to update it for each and every system.

Furthermore, locations allow for handle attachment where as an x,y does not.

I think it's quite useful for both spawning and custom combat systems. I'm not sure what other uses there are, but the spherical coordinate projection relative to a point made easy by PositionOrigin seems like it could make making really cool visual spells a bit easier =P.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Yea.. I've already used this in a combat system and am using it in a Spawn system... and I'm using the Spawn system for creep camp management and I've used a similar Spawn system for a footmen wars map.. I'm using the combat system in an RPG as well..

I designed this while designing a combat suite because when designing that suite, I realized that a lockable position was needed >.>. It would have been impossible to clean up the leaks otherwise.

The reason for the positions was because of targeting... it might be a splash attack that targets ground, or a specific attack that targets a unit, or a buff that targets an item, or something... who knows, hence Position.. it only made sense to box it up.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Actually, as the first post says, I initially made this for a combat system... when a target is passed around across multiple resources, that target may be anything (location, unit, destructable, item) and it may be used by many things. If it's used by many things, when do you know to destroy a location?

I hardly see a case where you don't know what is the nature of the target.

Furthermore, if you have a spawn, the origin of that spawn may be a location, unit, destructable or item.

And ?

Also, I disagree with how useful locations are... if you share a location across multiple systems, then you can update that location, which will properly update all of the systems. If you use x,y, then you have to update it for each and every system.

You still can use a struct.

Furthermore, locations allow for handle attachment where as an x,y does not.

I don't see the point of a location attachement.

I think it's quite useful for both spawning and custom combat systems. I'm not sure what other uses there are, but the spherical coordinate projection relative to a point made easy by PositionOrigin seems like it could make making really cool visual spells a bit easier =P.

Concrete example plz.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I hardly see a case where you don't know what is the nature of the target.

The target of an attack or spell could again be anything.. I once saw a spell in a map that could target items or units and acted differently for each.

>.>... if you're doing a generic custom combat system, you want to be able to support any and all possible targets.

If you're doing generic spawning, you want to be able to support any and all origins.

For both cases, any and all means that you have no clue what you're referencing.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
The target of an attack or spell could again be anything.. I once saw a spell in a map that could target items or units and acted differently for each.

Ok, but still no need of location usage.
And for this special case it's pretty easy to figure which type of target it is.
But i'm agree it becomes annoying when you have more than 2 target type.

>.>... if you're doing a generic custom combat system, you want to be able to support any and all possible targets.

Locations are not needed.
I hate create handles when it's useless.

If you're doing generic spawning, you want to be able to support any and all origins.

Locations are not needed ?

For both cases, any and all means that you have no clue what you're referencing.

I admit that in some cases you have to determine the type of the target, but locations are still not needed.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Theoretical Example (last and only one, argument closed)

Let's say that you have an effect that is attached to a position. You can attach that effect to a position two ways, by an x,y coordinate or by a location. Well, the location there seems totally pointless as the x,y would be simple array reads/writes + moving the effect around, so you go with the x,y. Now if you want to move the effect, it's simple and totally makes sense.

Now you have a spawn that's spawning at that position with the effect (2 totally unrelated things, but both referencing the same position), so you use x,y to easily attach it.

What happens when you move that position? First off, how do you know which things are using that position? You don't. Even if you did, you would have to update each and every little thing that was using that position...

If you were using locations, it'd be very simple... move the location and you're done.

That is the benefit of using locations, and if you still don't get it, then I don't know what to tell you.

Also, x,y coordinates aren't used in this Position script so that resources don't have to be specially coded to use this.

Don't use coordinates if you are referencing a position that can be changed because that's a horrible practice.

Argument closed.

edit
adding x,y,z coordinates and a create method o-o. I see a pretty good use for them w/ the origin stuff =). The type will be POSITION o-o, and an isPos will be added =O. With these, you don't have to check if valid etc... they can't be used for trigger events or anything spectacular, but they would be useful for spells and positions relative to origins (for example, really cool spawning). They are useful here because they don't need to be added to an update timer for locking, the x,y,z can just return their proper values relative to the origin.
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
Because by using this system, you may not just want to use locs... you want to be able to reference any type of position =P


Also, if you use locs that are passed around to other systems, then you need some sort of lock/unlock mechanism, or you won't know when to destroy those locations.

Let's say that there is a timed effect at a loc... a system that is in charge of spells uses some custom spell and passes in that loc. It also passes in that loc to another spell (2 spells targeting the same position).

How do you know when to destroy the loc? A simple lock/unlock would be the easiest way =).
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
You can consider me as a fool or/and as a stupid guy, but i still don't see the problem with using coordinates X/Y instead.

Why the hell would i have 2 or more totally unrelated things which use the same position, and then suddenly i want to link them and move the position for each of them.
I mean it's related or it's unrelated, can't be both.

And if it's related i still can use a struct and anyway it's more likely i will have to link more data, and so the struct is not a waste.
 
Level 12
Joined
Mar 28, 2005
Messages
160
to be honest, there is never an instance that I can think of where I would need to use this, that is why I ask

You can consider me as a fool or/and as a stupid guy, but i still don't see the problem with using coordinates X/Y instead.

First, why the hell would i have 2 or more totally unrelated things which use the same position, and then suddenly i want to link them and move the position for each of them.
I mean it's related or it's unrelated, can't be both.

And if it's related i still can use a struct and anyway it's more likely i will have to link more data, and so the struct is not a waste.

QFT, what I wanted to say but wasn't able to put into words
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I say the cloud and spawn are unrelated but use the same position, so that's how it's going to be.

It's my theoretical thingie, you can't change it >.>.

If you couple them together, then you have to redo the cloud for attacks and etc... I say the cloud can be used by itself as well, or with a spawn. And the spawn doesn't have to be linked to a cloud, it could also be on a mountain or a ship. Why? Because I say so, it's my theoretical thingie.

The only link they have between them is the spot =P, so take that, and that is only because I say so. They might not have the same spot, they only do because in this instance I say they do.

And there is a cloud that is linked to a mountain without a spawn, so boom.

Do you get it yet?

never ever couple or the couple monsters will come after you

And here is another fact. If your only argument is that this is useless (no concrete evidence or anything), then it's pointless to argue with me. You are totally wasting your time right now because I'm never going to agree with you.

For example, in that weird Value thing that Alain wrote, I showed him precisely why it was useless. In UnitTypeIndexer, that was useless because of the chaos ability.

Essentially, it's impossible to prove that this is useless because it would either have to be broken with no possible fix or it would have to be incredibly simple to do (talking like 3 lines total) another way (exact, and I mean exact same features supported).

So just give up the this is useless argument. The fact that I'm using it means that you're obviously wrong. Until you provide concrete evidence, this is a total waste of time. Until I see evidence, I'm going to ignore any arguments that this is useless since I'm done wasting my time ^)^.

-----
JASS:
set spawn.origin = position //any type of position
set spawn.origin.x = 33 //woo, easily moved it for everything that uses it

call attack(position) //if the position is a unit or destructable, 
                           //direct attack w/ homing, if it's a position, 
                           //ground attack with enum, if it's an item, debuff the item

Now on to doing the necessary updates on this and fixing FlatFlier and adding a condition in an if statement to SimpleSpawn.
 
Last edited:
Cool library ^^
I wrote something similar to it in C++ 2 weeks ago ;D

EDIT:
haha
You just redefined the "location" object ^^
JASS:
class location
{
    public:
        float getLocationX(void)
        {
             return x;
        }
        float getLocationY(void)
        {
             return y;
        }
        float getLocationZ(void)
        {
             return z;
        }
        // ... more functions bla bla bla

    private:
        float x;
        float y;
        float z;
};

Whatever Blizzard did (Something more advanced than this but still similar)
is a piece of shit compared to what you invoked xD

JASS:
// Location.h
// A location class header file for reusability
#include <cmath>
#include <cstdlib>
#include <iostream>
using namespace std;

const double pi = 3.141592653589793238462643383;
const double d2r = pi/180.0;
const double r2d = 180.0/pi;

class Location
{
	public:
		// The constructor for each object
		Location(double xn, double yn, double zn)
		{
			setLocationX( xn );
			setLocationY( yn );
			setLocationZ( zn );
		}

		// The Get functions
		double getLocationX()
		{
			return x;
		}

		double getLocationY()
		{
			return y;
		}

		double getLocationZ()
		{
			return z;
		}
		
		// The Set functions
		void setLocationX( double newx )
		{
			x=newx;
		}

		void setLocationY( double newy )
		{
			y=newy;
		}

		void setLocationZ( double newz )
		{
			z=newz;
		}

		void applyVector( double ax, double ay, double az )
		{
			x=x+ax;
			y=y+ay;
			z=z+az;
		}

		double getDistanceBetweenLocations( double ox, double oy )
		{
			double bx = (ox-x) * (ox-x);
			double by = (oy-y) * (oy-y);
			return sqrt( bx+by );
		}

		double getDistanceBetweenLocationsEx( double ox, double oy, double oz )
		{
			double bx = (ox-x) * (ox-x);
			double by = (oy-y) * (oy-y);
			double bz = (oz-z) * (oz-z);
			return sqrt( bx+by+bz );
		}

		void destroyLocation()
		{
			x = 0.0;
			y = 0.0;
			z = 0.0;
                                      // still WiP
		}

		void displayCoordinates()
		{
			cout << "The location X is: " << x << endl;
			cout << "The location Y is: " << y << endl;
			cout << "The location Z is: " << z << endl;
		}

		double getAngleToLocation( double ax, double ay )
		{
			return atan2(ay-y,ax-x) * r2d;
		}

		void applyProjection( double distance, double angle )
		{
			x = x + distance * sin(angle * d2r);
			y = y + distance * cos(angle * d2r);
		}

	private:
		double x;
		double y;
		double z;
};
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I say the cloud and spawn are unrelated but use the same position, so that's how it's going to be.

I still don't have any example where several unrelated things would use the same point, that doesn't make sense.

It's my theoretical thingie, you can't change it >.>.

I know, you never change your mind.

If you couple them together, then you have to redo the cloud for attacks and etc... I say the cloud can be used by itself as well, or with a spawn. And the spawn doesn't have to be linked to a cloud, it could also be on a mountain or a ship. Why? Because I say so, it's my theoretical thingie.

That's the problem, it has only a theorical purpose, not a concret one.

The only link they have between them is the spot =P, so take that, and that is only because I say so. They might not have the same spot, they only do because in this instance I say they do.

Linked only to a point, weird.

And there is a cloud that is linked to a mountain without a spawn, so boom.

What ?

Do you get it yet?

No.

never ever couple or the couple monsters will come after you

What ?

And here is another fact.

The only fact so far is that you won't change your mind.

If your only argument is that this is useless (no concrete evidence or anything), then it's pointless to argue with me. You are totally wasting your time right now because I'm never going to agree with you.

I will wait for a concrete example of use (short if possible) to change my mind or not, for the moment i still don't see the usefulness.

Essentially, it's impossible to prove that this is useless because it would either have to be broken with no possible fix or it would have to be incredibly simple to do (talking like 3 lines total) another way (exact, and I mean exact same features supported).

Uneeded features are uneeded. (but again i could change my mind later, i just have any concrete example yet)

So just give up the this is useless argument. The fact that I'm using it means that you're obviously wrong.

Sure, you're perfect you never do bad things, and even always do it in the best way possible ever, you're not an human after all (irony).

-----
JASS:
set spawn.origin = position //any type of position
set spawn.origin.x = 33 //woo, easily moved it for everything that uses it

call attack(position) //if the position is a unit or destructable, 
                           //direct attack w/ homing, if it's a position, 
                           //ground attack with enum, if it's an item, debuff the item

EDIT :

That would make sense if a destructable could be moved.
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
Finished the next updates...

haven't tested x,y,z setters (all) or x,y,z (position type) getters with PositionOrigin enabled, but everything else has been tested =P.

It's kinda cool... was moving a peasant around and 2 units were tied to it o-o.

JASS:
struct tests extends array
    private static method onInit takes nothing returns nothing
        local Position p = Position[CreateUnit(Player(0), 'hpea', WorldBounds.centerX, WorldBounds.centerY, 270)]
        local Position p3 = Position[CreateUnit(Player(0), 'hfoo', WorldBounds.centerX, WorldBounds.centerY, 180)]
        local Position p4 = Position[CreateUnit(Player(0), 'hrif', WorldBounds.centerX, WorldBounds.centerY, 0)]
        set p.z = 300
        set p3.z = 450
        set p4.z = 150
        set p3.x = WorldBounds.centerX
        set p3.y = WorldBounds.centerY+300
        set p4.x = WorldBounds.centerX
        set p4.y = WorldBounds.centerY-300
        call p.lock()
        call p3.lock()
        set p3.origin = p
        set p3.locked = true
        call p4.lock()
        set p4.origin = p
        set p4.locked = true
        set p3.relative = true
        set p4.relative = true
    endmethod
endstruct

Let's see, it maintained facing, x, y, and z position relative to the origin's facing, x, y, and z position. So yea... if a footmen was to the right of a peasant and was facing towards the peasant (peasant facing downwards), that peasant could move around etc and that footmen would continue to face that peasant. If that peasant faced upwards, the footmen would be on the left, etc... it's position is relative to the origin's x, y, z, and facing =P.

I worked pretty hard on this script, but it was worth it =).


If anyone runs into any bugs w/ it, please let me know so I can fix them =P. I really scanned this over thoroughly in order to fix any logical errors, but you never now, I did it with very tired eyes so I could have missed sumtin =P.

On to Spawn and CombatSuite >: D.

Oh, and position types don't run in the timer >: P, so they are very good to use when you need positions relative to another position.

And you can ofc have positions relative to positions relative to more positions.

I was thinking of cool things, like a huge moving ship =P. This essentially allows pretty easy composite unit creation.

Keep in mind that the overhead on PositionOrigin is pretty hefty because it does have to run on a timer to keep everything in the right spot :\.

edit
optimized PositionOrigin a bit... went from lagging at 100 instances to smooth at 200. I don't suggest mass use of PositionOrigin with non position type positions >; p

With even 8000 position type positions, PositionOrigin would run smoothly because they aren't added to timer. Only lock unit positions to an origin or w/e for funky special effects =).

edit
another cool demo (spiral staircase thing)
JASS:
struct tests extends array
    private static integer i = 100
    private static Position p
    private static real r = 0
    private static integer is = 0
    private static Position array pos
    private static method ca takes nothing returns nothing
        local integer x = is
        loop
            exitwhen x == 0
            set x = x - 1
            set pos[x].theta = pos[x].theta + .06283185
        endloop
    endmethod
    private static method cr takes nothing returns nothing
        local Position p2
        local integer x = 50
        set i = i - 50
        if (i <= 0) then
            set x = x + i
            call PauseTimer(GetExpiredTimer())
            call DestroyTimer(GetExpiredTimer())
        endif
        loop
            exitwhen x == 0
            set x = x - 1
            set p2 = Position[CreateUnit(Player(0), 'hfoo', WorldBounds.centerX, WorldBounds.centerY, 180)]
            set pos[is] = p2
            set is = is + 1
            call p2.lock()
            set p2.origin = p
            set p2.locked = true
            set p2.theta = r
            set p2.phi = 1.57079632
            set p2.distance = 500
            set p2.relative = false
            set r = r + .06283185
            set p2.z = is*5
        endloop
    endmethod
    private static method onInit takes nothing returns nothing
        set p = Position[CreateUnit(Player(0), 'hpea', WorldBounds.centerX, WorldBounds.centerY, 270)]
        call p.lock()
        set p.z = 500
        call TimerStart(CreateTimer(), .03125, true, function thistype.cr)
        call TimerStart(CreateTimer(), .03125, true, function thistype.ca)
    endmethod
endstruct

edit
position types don't seem to be working right

also performed some updates to the script to remove a lot of code =)

edit
while fixing, I've been playing with it

Here is a rotating helix o-o

I made some cool ferris wheel thingies too, and if you uncomment the phi translation, this thing looks crazy Oo.
JASS:
struct tests extends array
    private static constant integer A = 25
    private static integer i = A
    private static Position p
    private static real r = 6.28318530/(A+0.)
    private static integer is = 0
    private static Position array pos
    private static method ca takes nothing returns nothing
        local integer x = is
        local real h
        local real m = p.x
        local real v = p.y
        loop
            exitwhen x == 0
            set x = x - 1
            set pos[x].theta = pos[x].theta + .06283185
            //set pos[x].phi = pos[x].phi + 0.1256637
            //set h = pos[x].theta
            //set pos[x].x = 250*Cos(h)+m
            //set pos[x].y = 250*Sin(h)+v
        endloop
    endmethod
    private static method cr takes nothing returns nothing
        local Position p2
        local Position p3
        local integer x = 50
        set i = i - 50
        if (i <= 0) then
            set x = x + i
            call PauseTimer(GetExpiredTimer())
            call DestroyTimer(GetExpiredTimer())
        endif
        loop
            exitwhen x == 0
            set x = x - 1
            //set p3 = Position.create(0,0,0)
            set p3 = Position[CreateUnit(Player(0), 'hfoo', WorldBounds.centerX, WorldBounds.centerY, 180)]
            set pos[is] = p3
            set is = is + 1
            call p3.lock()
            set p3.origin = p
            set p3.locked = true
            
            set p3.theta = r+1.57079632
            set p3.phi = r
            set p3.distance = 200
            set p3.relative = false
            set r = r + 6.28318530/(A+0.)
            set p3.z = 300/(A+0.)*is
            /*
            set p2 = Position[CreateUnit(Player(0), 'hfoo', WorldBounds.centerX, WorldBounds.centerY, 180)]
            call p2.lock()
            set p2.origin = p3
            set p2.locked = true
            set p2.theta = 0
            set p2.phi = 1.57079632
            set p2.distance = 0
            set p2.relative = true
            */
        endloop
    endmethod
    private static method onInit takes nothing returns nothing
        set p = Position[CreateUnit(Player(0), 'hpea', WorldBounds.centerX, WorldBounds.centerY, 270)]
        call p.lock()
        set p.z = 350
        call TimerStart(CreateTimer(), .03125, true, function thistype.cr)
        call TimerStart(CreateTimer(), .03125, true, function thistype.ca)
    endmethod
endstruct

I really want to make a circle where the left side translates by phi one way and the right side translates by phi the other way, and I want to do so with minimal effort ; (.

I had a helix thing that was bending itself to create really psychedelic thingies, and that's what made me think that the circle would be cool.

Another cool shape would be a hyperbola ^)^, and a sphere where all of the thingies go towards the top and converge into a beam (a laser canon??).

I'm having too much fun with this... rofl
 
Last edited:
Level 7
Joined
Oct 11, 2008
Messages
304
You forget to remove the PositionOrigin from the modules ^_^

JASS:
static if LIBRARY_PositionOrigin then
                if (o.va and l) then
                    return rot+o.facing
                endif
            endif

//

static if LIBRARY_PositionOrigin then
                if (originOwner and o.va) then
                    return o.owner
                elseif (isItem and IsItemOwned(item)) then
                    return GetOwningPlayer(GetItemOwner(item))
                elseif (isUnit) then
                    return GetOwningPlayer(unit)
                endif
            else
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
JASS:
        //is handle type properties
        public method operator isLoc takes nothing returns boolean
            return type == LOC
        endmethod
        public method operator isUnit takes nothing returns boolean
            return type == UNIT
        endmethod
        public method operator isDest takes nothing returns boolean
            return type == DEST
        endmethod
        public method operator isItem takes nothing returns boolean
            return type == ITEM
        endmethod
        public method operator isPos takes nothing returns boolean
            return type == POSITION
        endmethod

Why not just make "type" readonly?
 
Top