• 🏆 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!

[vJASS] BoundOffset

Level 6
Joined
Jan 9, 2019
Messages
102
JASS:
library BoundOffset requires VectorBase //wc3_v1.29+
//== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
//  ________________
//   #  BoundOffset
//          v6.1b, by Overfrost
//	----------------------------
//
//    - implements VectorBase as offset
//
//    - either offsets from (0,0,0) or from a unit's position
//
//  ______________
//   #  Requires:
//
//	  v Warcraft3 v1.29+
//    - VectorBase
//          hiveworkshop.com/threads/vectorbase.311604
//
//== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
//! novjass

    //
    struct BoundOffset extends array

        //-------------
        // Instancers
        //
        static method create takes nothing returns thistype
        //
        method lock takes nothing returns nothing
        method unlock takes nothing returns boolean
        // - unlock replaces destroy, returns true if it destroys
        //

        //----------------
        // Offset Fields
        //
        real offset.x = 0
        real offset.y = 0
        real offset.z = 0
		//
		real offset.r
		real offset.t
		real offset.p
		real offset.s
		//

		//-----------------
		// Offset Methods
		//
		method offset.xyz takes real x, real y, real z returns thistype(this)
		method offset.rtp takes real r, real t, real p returns thistype(this)
		method offset.stz takes real s, real t, real z returns thistype(this)
		// - 3d multi-value assigners
		//
		method offset.xy takes real x, real y returns thistype(this)
		method offset.st takes real s, real t returns thistype(this)
		// - 2d multi-value assigners
		//
		method offset.rotate takes real t, real p returns thistype(this)
		// - rotator, use 0 as p for 2d rotations
		//

		//-------------------
		// Resultant Fields
		//
        readonly real x
        readonly real y
        readonly real z
        // - returns the coordinate of origin + (offset.x,offset.y,offset.z)
        // - origin is the current coordinates of bound unit
        // - if no unit is bound, origin is (0,0,0)
        //
		readonly real r  // rho
		readonly real t  // theta
		readonly real p  // phi
		readonly real s  // side
		// - returns the corresponding value of resultant
		// - resultant is defined as (x,y,z)
		//

		//--------------
		// Bond Fields
		//
        readonly unit unit = null
        readonly boolean bound
        // - bound = true if unit isn't null
        //

        //-----------------
        // Binder Methods
        //
        method bind takes unit u returns thistype(this)
        // - binds the offset to a unit
        // - affects the return value of x, y, z
        //
        method unbind takes nothing returns thistype(this)
        // - unbinds the offset from the bound unit
        // - doesn't change any value of offset
		// - thus changing what x, y, z return
        //
        method debind takes nothing returns thistype(this)
        // - sets (x,y,z) to (offset.x, offset.y, offset.z)
        // - then unbinds the offset from the bound unit
		// - thus what x, y, z return doesn't change
        //

//! endnovjass
//-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

//
private struct ps extends array
	implement VectorExt
endstruct
struct BoundOffset extends array
    implement Alloc

	//
    private integer pLock

    //---------
	// fields
    readonly unit unit

    //
    static method create takes nothing returns thistype
        local thistype this = allocate()
        set pLock = 0
        //
        set ps(this).x = 0
        set ps(this).y = 0
        set ps(this).z = 0
        //
        return this
    endmethod

	//---------
	// offset
	method operator offset takes nothing returns ps
		return this
	endmethod

    //------
	// xyz
    method operator x takes nothing returns real
        if (unit != null) then
            return GetUnitX(unit) + ps(this).x
        endif
		//
        return ps(this).x
    endmethod
    method operator y takes nothing returns real
        if (unit != null) then
            return GetUnitY(unit) + ps(this).y
        endif
		//
        return ps(this).y
    endmethod
    method operator z takes nothing returns real
        if (unit != null) then
            return GetUnitFlyHeight(unit) + BlzGetLocalUnitZ(unit) + ps(this).z
        endif
		//
        return ps(this).z
    endmethod

	//-------
	// rtps
	method operator r takes nothing returns real
		local real lX = x
		local real lY = y
		local real lZ = z
		//
		return SquareRoot(lX*lX + lY*lY + lZ*lZ)
	endmethod
	method operator s takes nothing returns real
		local real lX = x
		local real lY = y
		//
		return SquareRoot(lX*lX + lY*lY)
	endmethod
	//
	method operator t takes nothing returns real
		return Atan2(y, x)
	endmethod
	method operator p takes nothing returns real
		return Atan2(s, z)
	endmethod

	//--------------
	// bond fields
    method operator bound takes nothing returns boolean
        return unit != null
    endmethod

	//---------------
    // bond handler
    method bind takes unit aUnit returns thistype
        set unit = aUnit
		//
        return this
    endmethod
    //
    method unbind takes nothing returns thistype
	//! textmacro P_BOUND_OFFSET_UNBIND
			//
			set unit = null
			//
			return this
			//
	//! endtextmacro
	//! runtextmacro P_BOUND_OFFSET_UNBIND()
    endmethod
    method debind takes nothing returns thistype
        set ps(this).x = x
        set ps(this).y = y
        set ps(this).z = z
        //
	//! runtextmacro P_BOUND_OFFSET_UNBIND()
    endmethod

    //
    method lock takes nothing returns nothing
        set pLock = pLock + 1
    endmethod
    method unlock takes nothing returns boolean
        set pLock = pLock - 1
        if (pLock < 0) then
            //
            set unit = null
            //
            call deallocate()
            return true
        endif
        return false
    endmethod
endstruct

endlibrary
JASS:
//
function GetUnboundOffset takes real aX, real aY, real aZ returns BoundOffset
    return BoundOffset.create().offset.xyz(aX, aY, aZ)
endfunction
//
function GetBoundOffset takes unit aUnit returns BoundOffset
    return BoundOffset.create().bind(aUnit)
endfunction
//
function GetUnitOffset takes unit aUnit, real aOffX, real aOffY, real aOffZ returns BoundOffset
    return BoundOffset(BoundOffset.create().bind(aUnit).offset.xyz(aOffX, aOffY, aOffZ)).debind()
    // please don't ask me why it's like this
    // simply put, it's to avoid an error
endfunction
// all above works correctly
// because all of those methods return this (this instance)

//
function GetOffsetLengthSquared takes BoundOffset aOff returns real
    return aOff.x*aOff.x + aOff.y*aOff.y + aOff.z*aOff.z
    // automatically considers unit position (if any is bound)
endfunction
Changelog:
  • v6.1b: Re-optimized the code a little, fixed documentation.
  • v6.1a: Now properly offsets from z(0). Previously the resultant z would consider terrain height.
  • v6.0a:
    - Moved the VectorExt implementer to another struct, accessible by offset.
    - Reverted back names that use res prefix. Now they don't use any prefix.
  • v5.1b: Renamed private/local variables to longer names.
  • v5.1a:
    - Now implements Alloc instead of AllocFast due to an update on VectorBase.
    - Moved examples from inside the code to the thread.
    - Rewritten API documentation.
  • v5.0a: Renamed the prefix r to res (rx to resX, etc).
  • v4.0b: Fixed and improved documentation.
  • v4.0a:
    - Renamed tx, ty, tz to rx, ry, rz
    - Added rr, rt, rp, and rs
  • v3.0a:
    - No longer uses ItemPosition
    - Now requires Warcraft3 v1.29+
    - Removed bindItem, renamed bindUnit to bind
    - Renamed bindOrigin to unbind, and the previous unbind to debind
  • v2.0a:
    - Now uses VectorBase
    - Changed coordinates API
    - Fixed tz for items
    - Added boolean bound
  • v1.0b: Changed return value of unlock to boolean.
 
Last edited:
Top