Run global function from local player blocks!

Status
Not open for further replies.
Level 24
Joined
Aug 1, 2013
Messages
4,658
After messing around with my UI system, I suddenly had a few nice ideas for my UIButton, which lead me to a bothersome situation where I had an if statement that checked some data of a local player but had to execute an event for all players (as a button click could essentially be buying/selling an item, learning/leveling an ability, joining/leaving a team, selecting a unit (hero), or whatever).

I didnt end up having to use this script to make it work, but I think it is still pretty neat to have:
JASS:
//! novjass
struct Function
    public static method create takes code execution returns thistype
    public method run takes nothing returns nothing
//! endnovjass

For example a camera position event...
Sending actual data is not done by this script.
JASS:
struct Function
    ////////////////////////////////////////////////////////
    // BE AWARE NOT TO CALL .run() AS TRIGGER EVALUATION! //
    ////////////////////////////////////////////////////////
  
    private static constant group SELECTION = CreateGroup()
  
    private static constant player DUMMY_OWNER = Player(15)
    private static constant integer DUMMY_TYPE = 'h000'
    private static constant real DUMMY_X = -2560
    private static constant real DUMMY_Y = -2560
  
    private unit dummy
    private trigger trig
  
    public static method create takes code execution returns thistype
        local thistype this = .allocate()
      
        // create dummy, link struct instance, add ghost and remove pathing.
        // create trigger and add execution as Condition().
      
        set .dummy = CreateUnit(.DUMMY_OWNER, .DUMMY_TYPE, .DUMMY_X, .DUMMY_Y, 0)
        call SetUnitUserData(.dummy, this)
        call UnitAddAbility(.dummy, 'Aeth')
        call SetUnitPathing(.dummy, false)
      
        set .trig = CreateTrigger()
        call TriggerAddCondition(.trig, Condition(execution))
      
        return this
    endmethod
  
    public method run takes nothing returns nothing
        local unit FoG
      
        // save previous selection
        // select dummy
        // re-select previous selection
      
        call GroupEnumUnitsSelected(.SELECTION, GetLocalPlayer(), null)
        call ClearSelection()
        call SelectUnit(.dummy, true)
        call ClearSelection()
        loop
            set FoG = FirstOfGroup(.SELECTION)
            exitwhen FoG == null
            call GroupRemoveUnit(.SELECTION, FoG)
          
            call SelectUnit(FoG, true)
        endloop
    endmethod
  
    private static method onSelect takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local thistype this
        if GetUnitTypeId(u) == .DUMMY_TYPE then
            set this = GetUnitUserData(u)
            call TriggerEvaluate(.trig)
        endif
        set u = null
        return false
    endmethod
  
    private static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELECTED)
        call TriggerAddCondition(t, Condition(function thistype.onSelect))
    endmethod
  
endstruct
JASS:
struct FunctionTest
  
    private static boolean isInside = false // local data (aka, can and will be different for different players)
    private static Function func
  
    private static method onActivated takes nothing returns nothing
        call BJDebugMsg("Camera entered region for player "+GetPlayerName(GetTriggerPlayer())+"("+I2S(GetPlayerId(GetTriggerPlayer()))+").")
    endmethod
  
    private static method onInterval takes nothing returns nothing
        local real x = GetCameraTargetPositionX()
        local real y = GetCameraTargetPositionY()
      
        if RectContainsCoords(gg_rct_Region_000, x, y) then
            if not .isInside then
                set .isInside = true
                //entered region
                call .func.run()
            endif
        else
            if .isInside then
                set .isInside = false
                //left region
            endif
        endif
    endmethod
  
    private static method onInit takes nothing returns nothing
        set .func = Function.create(function thistype.onActivated)
        call TimerStart(CreateTimer(), 0.03, true, function thistype.onInterval)
    endmethod
  
endstruct
 
Status
Not open for further replies.
Back
Top