View Single Post
Old 12-13-2010, 12:50 AM   #1
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,190

Submissions (19)

Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default UnitAppearanceTracker

A short script that allows you to get the current vertex color and scale of units.
Requires ARGB, Table and optionally AutoIndex.

Credit where credit is due: a library like this was first proposed by Tot here, but didn't merit an approval at the time. It was a useful idea, though, I had a use for it myself and since Tot doesn't appear to be active anymore, I decided to rework and submit it.

Collapse JASS:
library UnitAppearanceTracker requires ARGB, Table, optional AutoIndex

//*****************************************************************
//*  UNIT APPEARANCE TRACKER
//*
//*  written by: Anitarf
//*  original implementation: Tot
//*  requires: -ARGB
//*            -Table
//*  optional: -AutoIndex
//*
//*  There is no native way to get a unit's current vertex colour
//*  or scale in WC3. This library was written to work around this
//*  limitation. The library tracks changes made to the vertex
//*  colour and scale of individual units so that those values can
//*  be obtained for a specific unit at any time. Vertex color is
//*  described using ARGB. This library now also tracks the 
//*  animation speed of units.
//*
//*   local ARGB c = GetUnitVertexColor(u)
//*   local real s = GetUnitScale(u)
//*   local real s = GetUnitTimeScale(u)
//*
//*  If a unit type has a vertex colour or scale defined in the
//*  object editor that is different from the DEFAULT_COLOR/SCALE,
//*  UnitAppearanceTracker must be informed of this using the
//*  following functions in order for it to correctly assume these
//*  values for newly created units:
//*
//*   call SetUnitTypeVertexColor('nzom', 0xFFFF9696) // zombie
//*   call SetUnitTypeScale('hgry', 1.2) // gryphon rider
//*
//*  Finally, to be able to reset a unit's color and scale, the
//*  library provides the following functions that return the
//*  default values for a given unit type:
//*
//*   set c = GetUnitTypeVertexColor(GetUnitTypeId(u))
//*   set s = GetUnitTypeScale(GetUnitTypeId(u))
//*
//*  This library optionally requires AutoIndex. Without AutoIndex,
//*  the library still has full functionality, AutoIndex only makes
//*  it slightly faster, however it will only be able to track the
//*  appearance of indexed units.
//*****************************************************************

    globals
        // Set this to false if you want to track the appearance of units ignored by AutoIndex.
        private constant boolean USE_AUTOINDEX_IF_PRESENT = true
        // Multiplication factor used when converting reals to integers so they can be stored in Table.
        private constant real PRECISION = 1000.0

        // You do not need to call SetUnitTypeVertexColor/SetUnitTypeScale for units that use these default values,
        // so the values should match the most commonly used scale/colour in your map. Speed should always be 1.0.
        private ARGB DEFAULT_COLOR = 0xFFFFFFFF
        private real DEFAULT_SCALE = 1.0
        private real DEFAULT_SPEED = 1.0

// END OF CALIBRATION SECTION    
// ================================================================

        private ARGB array unitsColor
        private real array unitsScale
        private real array unitsSpeed
        private HandleTable unitColor
        private HandleTable unitScale
        private HandleTable unitSpeed
        
        private Table unittypeColor
        private Table unittypeScale
    endglobals

// ================================================================
// Hooks:

    private function SetUnitVertexColor_hook takes unit whichUnit, integer red, integer green, integer blue, integer alpha returns nothing
      static if USE_AUTOINDEX_IF_PRESENT and LIBRARY_AutoIndex then
        set unitsColor[GetUnitId(whichUnit)] = ARGB.create(alpha, red, green, blue)
      else
        set unitColor[whichUnit] = integer(ARGB.create(alpha, red, green, blue))
      endif
    endfunction
    private function SetUnitVertexColorBJ_hook takes unit whichUnit, real red, real green, real blue, real transparency returns nothing
        call SetUnitVertexColor_hook(whichUnit, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
    endfunction
    hook SetUnitVertexColor SetUnitVertexColor_hook
    hook SetUnitVertexColorBJ SetUnitVertexColorBJ_hook
    
    // ----------------------------------------------------------------

    private function SetUnitScale_hook takes unit whichUnit, real scaleX, real scaleY, real scaleZ returns nothing
      static if USE_AUTOINDEX_IF_PRESENT and LIBRARY_AutoIndex then
        set unitsScale[GetUnitId(whichUnit)] = scaleX
      else
        set unitScale[whichUnit] = R2I(scaleX*PRECISION)
      endif
    endfunction
    private function SetUnitScalePercent_hook takes unit whichUnit, real percentScaleX, real percentScaleY, real percentScaleZ returns nothing
        call SetUnitScale_hook(whichUnit, percentScaleX * 0.01, 0.0, 0.0)
    endfunction
    hook SetUnitScale SetUnitScale_hook
    hook SetUnitScalePercent SetUnitScalePercent_hook

    // ----------------------------------------------------------------

    private function SetUnitTimeScale_hook takes unit whichUnit, real timeScale returns nothing
      static if USE_AUTOINDEX_IF_PRESENT and LIBRARY_AutoIndex then
        set unitsSpeed[GetUnitId(whichUnit)] = timeScale
      else
        set unitSpeed[whichUnit] = R2I(timeScale*PRECISION)
      endif
    endfunction
    private function SetUnitTimeScalePercent_hook takes unit whichUnit, real percentScale returns nothing
        call SetUnitTimeScale_hook(whichUnit, percentScale * 0.01)
    endfunction
    hook SetUnitTimeScale SetUnitTimeScale_hook
    hook SetUnitTimeScalePercent SetUnitTimeScalePercent_hook

// ================================================================
// User functions:
    
    function GetUnitVertexColor takes unit u returns ARGB
      static if USE_AUTOINDEX_IF_PRESENT and LIBRARY_AutoIndex then
        return unitsColor[GetUnitId(u)]
      else
        return ARGB(unitColor[u])
      endif
    endfunction

    function GetUnitScale takes unit u returns real
      static if USE_AUTOINDEX_IF_PRESENT and LIBRARY_AutoIndex then
        return unitsScale[GetUnitId(u)]
      else
        return unitScale[u]/PRECISION
      endif
    endfunction

    function GetUnitTimeScale takes unit u returns real
      static if USE_AUTOINDEX_IF_PRESENT and LIBRARY_AutoIndex then
        return unitsSpeed[GetUnitId(u)]
      else
        return unitSpeed[u]/PRECISION
      endif
    endfunction

    // ----------------------------------------------------------------

    function GetUnitTypeVertexColor takes integer unitID returns ARGB
        if unittypeColor.exists(unitID) then
            return ARGB(unittypeColor[unitID])
        endif
        return DEFAULT_COLOR
    endfunction

    function GetUnitTypeScale takes integer unitID returns real
        if unittypeScale.exists(unitID) then
            return unittypeScale[unitID]/PRECISION
        endif
        return DEFAULT_SCALE
    endfunction

    // ----------------------------------------------------------------

    function SetUnitTypeVertexColor takes integer unitID, ARGB c returns nothing
        set unittypeColor[unitID]=integer(c)
    endfunction

    function SetUnitTypeScale takes integer unitID, real s returns nothing
        set unittypeScale[unitID]=R2I(s*PRECISION)
    endfunction

// ================================================================
// Initialization:

    private struct Initializer extends array

    private static method UnitEntersMap takes unit u returns nothing
      static if USE_AUTOINDEX_IF_PRESENT and LIBRARY_AutoIndex then
        set unitsScale[GetUnitId(u)] = GetUnitTypeScale(GetUnitTypeId(u))
        set unitsColor[GetUnitId(u)] = GetUnitTypeVertexColor(GetUnitTypeId(u))
        set unitsSpeed[GetUnitId(u)] = DEFAULT_SPEED
      else
        set unitScale[u] = R2I(GetUnitTypeScale(GetUnitTypeId(u))*PRECISION)
        set unitColor[u] = integer(GetUnitTypeVertexColor(GetUnitTypeId(u)))
        set unitSpeed[u] = R2I(DEFAULT_SPEED*PRECISION)
      endif
    endmethod
    private static method UnitEntersMapTrigger takes nothing returns boolean
        call .UnitEntersMap(GetFilterUnit())
        return false
    endmethod

    // ----------------------------------------------------------------

    private static method onInit takes nothing returns nothing
        local rect rc
        local region rg
        local trigger t
        set unittypeColor=Table.create()
        set unittypeScale=Table.create()

      static if LIBRARY_AutoIndex then
        call OnUnitIndexed(UnitEntersMap)
      static if not USE_AUTOINDEX_IF_PRESENT then
        set unitScale=Table.create()
        set unitColor=Table.create()
        set unitSpeed=Table.create()
      endif
      else
        set unitScale=Table.create()
        set unitColor=Table.create()
        set unitSpeed=Table.create()

        set rc=GetWorldBounds()
        set rg=CreateRegion()
        set t=CreateTrigger()
        call RegionAddRect(rg, rc)
        call RemoveRect(rc)
        call TriggerRegisterEnterRegion( t, rg, Condition(function Initializer.UnitEntersMapTrigger) )
        set rc=null
        set rg=null
      endif
    endmethod

    endstruct

endlibrary
__________________
Anitarf is offline   Reply With Quote
Sponsored Links - Login to hide this ad!