- Joined
- Apr 30, 2011
- Messages
- 359
JASS:
//========================================================================================
//
// [ Point ]
// -*- overcold_ice -*-
//
// An advanced version of location native
//----------------------------------------------------------------------------------------
//
// -[*] Features:
// - Simple operators and dynamic setups
// - Splits between ground height and z
// - Auto updated ground height
//----------------------------------------------------------------------------------------
//
// -[*] Configurables:
/*
private constant boolean AUTO_DESTROY
*/ //= enables/disables auto destroy, which automatically destroys the struct
// at the end of the thread if it has zero lock count
//----------------------------------------------------------------------------------------
//
// -[*] API:
/*
struct Point extends array
real x //= x-coordinate of the Point
real y //= y-coordinate of the Point
real z //= z-coordinate of the Point, doesn't include ground height
readonly real h //= ground height at the Point, automatically updated
static method operator create takes nothing returns Point
*/ //= allocator for the struct, zero lock count
// if AUTO_DESTROY then the struct is automatically destroyed
// at the end of the thread if it has zero lock count
/*
method lock takes nothing returns Point //= lock count +1
method unlock takes nothing returns Point //= lock count -1, destroy if 0
method break takes nothing returns Point //= destroy
*/ //= deallocator for the struct, the values still valid until
// a create operator is called
/*
static if AUTO_DESTROY then
method lastUse takes nothing returns nothing
endif
*/ //= destroys the struct at the end of the thread if it has zero
// lock count
/*
static method gh takes real x, real y returns real
*/ //= returns the ground height at (x, y) coordinate
/*
method sx takes real x returns Point
method sy takes real y returns Point
method sz takes real z returns Point
*/ //= sets x, y, z to those specified values
// allows single line setups
/*
method distXY takes real x, real y returns real
method distXYZ takes real x, real y, real z returns real
method distXYP takes Point p returns real
method distXYZP takes Point p returns real
*/ //= get the distance from this Point to another location specified
// by (x, y, z) coordinate or Point
// all of them inlines
/*
method angleXY takes real x, real y returns real
method angleXYZ takes real x, real y, real z returns real
method angleXYP takes Point p returns real
method angleXYZP takes Point p returns real
*/ //= get the angle from this Point to another location specified
// by (x, y, z) coordinate or Point in radians
// all of them inlines
//----------------------------------------------------------------------------------------
//
// -[*] Examples:
/*
local Point p1 = Point.create.sx(10).sy(20).sz(30).lock()
local Point p2 = Point.create.sx(100).sz(1000).lock()
local Point p3 = Point.create
set p3.x = 3651
set p3.y = p3.h
set p3.z = p3.y
call p3.unlock() //= -1 lock count, won't be destroyed (don't do this)
call p3.lock().lock().unlock() //= 0 lock count, will be destroyed (don't do this)
*/
/*
local real h1 = Point.create.sx(1000).sy(1000).break().h //= WORKS!!!
local real h2 = Point.gh(1000, 1000) //= same as above
*/
//----------------------------------------------------------------------------------------
//========================================================================================
library Point
//========================================================================================
// Configurables
//----------------------------------------------------------------------------------------
globals
private constant boolean AUTO_DESTROY = true
endglobals
//========================================================================================
struct Point extends array
private static integer c
private thistype r
private integer u
static if AUTO_DESTROY then
private thistype ad
private static timer t = CreateTimer()
endif
private static location l = Location(0, 0)
readonly real h
private real px
private real py
real z
static method gh takes real lx, real ly returns real
call MoveLocation(l, lx, ly)
return GetLocationZ(l)
endmethod
method sx takes real nx returns thistype
set px = nx
set h = gh(px, py)
return this
endmethod
method sy takes real ny returns thistype
set py = ny
set h = gh(px, py)
return this
endmethod
method sz takes real nz returns thistype
set z = nz
return this
endmethod
method operator x takes nothing returns real
return px
endmethod
method operator y takes nothing returns real
return py
endmethod
method operator x= takes real nx returns nothing
call sx(nx)
endmethod
method operator y= takes real ny returns nothing
call sy(ny)
endmethod
private static method dist takes real dx, real dy returns real
return SquareRoot(dx * dx + dy * dy)
endmethod
method distXY takes real lx, real ly returns real
return dist(lx - px, ly - py)
endmethod
method distXYP takes thistype l returns real
return distXY(l.x, l.y)
endmethod
method distXYZ takes real lx, real ly, real lz returns real
return dist(distXY(lx, ly), (gh(lx, ly) + lz) - (h + z))
endmethod
method distXYZP takes thistype l returns real
return dist(distXY(l.x, l.y), (l.h + l.z) - (h + z))
endmethod
private static method angle takes real dx, real dy returns real
return Atan2(dy, dx)
endmethod
method angleXY takes real lx, real ly returns real
return angle(lx - px, ly - py)
endmethod
method angleXYP takes thistype l returns real
return angleXY(l.x, l.y)
endmethod
method angleXYZ takes real lx, real ly, real lz returns real
return angle(distXY(lx, ly), (gh(lx, ly) + lz) - (h + z))
endmethod
method angleXYZP takes thistype l returns real
return angle(distXY(l.x, l.y), (l.h + l.z) - (h + z))
endmethod
private method recycle takes nothing returns nothing
if u == 0 then
set r = thistype(0).r
set thistype(0).r = this
endif
endmethod
method lock takes nothing returns thistype
set u = u + 1
return this
endmethod
method unlock takes nothing returns thistype
set u = u - 1
call recycle()
return this
endmethod
method break takes nothing returns thistype
set u = 0
call recycle()
return this
endmethod
static if AUTO_DESTROY then
private static method autoDestroy takes nothing returns nothing
local thistype this
loop
set this = thistype(0).ad
exitwhen this == 0
call this.recycle()
set thistype(0).ad = this.ad
endloop
endmethod
method lastUse takes nothing returns nothing
set u = u - 1
if thistype(0).ad == 0 then
call TimerStart(t, 0, false, function thistype.autoDestroy)
endif
set this.ad = thistype(0).ad
set thistype(0).ad = ad
endmethod
endif
static method operator create takes nothing returns thistype
local thistype this = thistype(0).r
if this == 0 then
set c = c + 1
set this = c
else
set thistype(0).r = this.r
endif
set this.px = 0
set this.py = 0
set this.z = 0
set this.h = 0
static if AUTO_DESTROY then
if thistype(0).ad == 0 then
call TimerStart(t, 0, false, function thistype.autoDestroy)
endif
set this.ad = thistype(0).ad
set thistype(0).ad = ad
endif
return this
endmethod
endstruct
endlibrary
Last edited: