• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Snippet] Press Spacebar Event

Level 18
Joined
Oct 20, 2007
Messages
353
[System] Press Spacebar and Backspaces Events

Following system allows to call functions when spacebar or backspace is pressed.
Made by me (D.O.G.). Please, give credits if used.
Map with working example attached to the post.

Few issues:
  • System work in single player only!
  • Requires dummy unit with TOWN HALL classification (for backspace event)
  • System doesn't work when SetCameraTargetController(Lock Camera) used (however system includes replacement functions).

Available functions:
  • function AddSpacebarAction takes code a returns triggercondition
  • function AddBackspaceAction takes code a returns triggercondition
  • function RemoveSpacebarAction takes triggercondition c returns nothing
  • function RemoveBackspaceAction takes triggercondition c returns nothing
  • function ClearSpacebarActions takes nothing returns nothing
  • function ClearBackspaceActions takes nothing returns nothing
  • function EnableSpacebarEvent takes boolean enable returns nothing
  • function EnableBackspaceEvent takes boolean enable returns nothing

Functions to replace SetCameraTargetController:
  • function LockCameraToUnit takes unit u returns nothing
  • function LockCameraToPoint takes real x, real y returns nothing
  • function LockCameraToPointLoc takes location loc returns nothing
  • function UnLockCamera takes nothing returns nothing

JASS:
library SpaceHandlerLocal initializer Init // by D.O.G. version 6.0
    
    /* SETTINGS */
    globals
        private constant real Period = 0.01562500
        // Unit must have TOWN HALL classification!!!
        private constant integer DummyUnit = 'u000'
    endglobals
    /* SETTINGS END */
    
    
    globals
        private real Space_X = 1000000000.0
        private real Space_Y = 1000000000.0
        private real Backspace_X = 1000000000.0
        private real Backspace_Y = 1000000000.0
        private real Lock_X = 1000000000.0
        private real Lock_Y = 1000000000.0
        private boolean Space_Enabled = false
        private boolean Backspace_Enabled = false
        private timer Timer = CreateTimer()
        private trigger Space_Actions = CreateTrigger()
        private trigger Backspace_Actions = CreateTrigger()
        private unit Backspace_Unit = null
        private unit Lock_Unit = null
        private integer Lock_Mode = 0
    endglobals
   
    function AddSpacebarAction takes code a returns triggercondition
        return TriggerAddCondition(Space_Actions, Condition(a))
        return null
    endfunction
    function AddBackspaceAction takes code a returns triggercondition
        return TriggerAddCondition(Backspace_Actions, Condition(a))
        return null
    endfunction
    function RemoveSpacebarAction takes triggercondition c returns nothing
        call TriggerRemoveCondition(Space_Actions, c)
    endfunction
    function RemoveBackspaceAction takes triggercondition c returns nothing
        call TriggerRemoveCondition(Backspace_Actions, c)
    endfunction
    function ClearSpacebarActions takes nothing returns nothing
        call TriggerClearConditions(Space_Actions)
    endfunction
    function ClearBackspaceActions takes nothing returns nothing
        call TriggerClearConditions(Backspace_Actions)
    endfunction
    function EnableSpacebarEvent takes boolean enable returns nothing
        local integer p
        set Space_Enabled = enable
        if not enable then
            set p = GetPlayerStartLocation(GetLocalPlayer())
            call SetCameraQuickPosition(GetStartLocationX(p), GetStartLocationY(p))
        endif
    endfunction
    function EnableBackspaceEvent takes boolean enable returns nothing
        set Backspace_Enabled = enable
        if not enable then
            call RemoveUnit(Backspace_Unit)
        endif
    endfunction
    function LockCameraToUnit takes unit u returns nothing
        set Lock_Unit = u
        set Lock_Mode = 1
    endfunction
    function LockCameraToPoint takes real x, real y returns nothing
        set Lock_X = x
        set Lock_Y = y
        set Lock_Mode = 2
    endfunction
    function LockCameraToPointLoc takes location loc returns nothing
        set Lock_X = GetLocationX(loc)
        set Lock_Y = GetLocationY(loc)
        set Lock_Mode = 2
    endfunction
    function UnLockCamera takes nothing returns nothing
        set Lock_Unit = null
        set Lock_Mode = 0
    endfunction
    
    private function Handler takes nothing returns nothing
        local real x = GetCameraTargetPositionX()
        local real y = GetCameraTargetPositionY()
        if Lock_Mode == 1 then
            set Lock_X = GetUnitX(Lock_Unit)
            set Lock_Y = GetUnitY(Lock_Unit)
        endif
        if Space_Enabled then
            if ((x == Space_X) and (y == Space_Y)) then
                call TriggerEvaluate(Space_Actions)
            else
                set Space_X = x
                if Lock_Mode > 0 then
                    call PanCameraTo(Lock_X, Lock_Y)
                endif
            endif
            set Space_Y = y + 0.01
            call SetCameraQuickPosition(Space_X, Space_Y)
        endif
        if Backspace_Enabled then
            if ((x == Backspace_X) and (y == Backspace_Y)) then
                call TriggerEvaluate(Backspace_Actions)
            else
                set Backspace_Y = y
                if Lock_Mode > 0 then
                    call PanCameraTo(Lock_X, Lock_Y)
                endif
            endif
            set Backspace_X = x + 0.01
            call RemoveUnit(Backspace_Unit)
            set Backspace_Unit = CreateUnit(GetLocalPlayer(), DummyUnit, Backspace_X, Backspace_Y, 270.0)
            call SetUnitPosition(Backspace_Unit, Backspace_X, Backspace_Y)
        endif
    endfunction


    private function Init takes nothing returns nothing
        call TimerStart(Timer, Period, true, function Handler)
    endfunction

endlibrary

Testing trigger for local version.

JASS:
library SpaceHandlerLocalTester initializer Init requires SpaceHandlerLocal
    
    globals
        private integer msg = 0
    endglobals
    
    private function SpacePressed takes nothing returns nothing
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 1.0, "[" + I2S(msg) + "] You have pressed spacebar!")
        set msg = msg + 1
    endfunction
    
    private function BackspacePressed takes nothing returns nothing
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 1.0, "[" + I2S(msg) + "] You have pressed backspace!")
        set msg = msg + 1
    endfunction
    
    
    private function Init takes nothing returns nothing
        
        call AddSpacebarAction(function SpacePressed)
        call AddBackspaceAction(function BackspacePressed)
        
        call LockCameraToUnit(gg_unit_Hpal_0005)
        
        call EnableSpacebarEvent(true)
        call EnableBackspaceEvent(true)
        
    endfunction
   
endlibrary

Multiplayer version. Works for now only for message showing))
I need help with this one)

JASS:
library SpaceHandler initializer Init // by D.O.G. version 5.5
   
    globals
        private real Space_X = 1000000000.0
        private real Space_Y = 1000000000.0
        private timer Space_Timer = CreateTimer()
        private trigger Space_Actions = CreateTrigger()
        private boolean Not_Sync = true
        private gamecache Cache
        private integer Local_I
        private string Local_S
        private player Space_Player = null
    endglobals
   
    function AddSpacebarAction takes code a returns triggercondition
        return TriggerAddCondition(Space_Actions, Condition(a))
        return null
    endfunction
    
    function GetSpacePlayer takes nothing returns player
        return Space_Player
    endfunction
    
    
    private function Handler takes nothing returns nothing
        local real x = GetCameraTargetPositionX()
        local real y = GetCameraTargetPositionY()
        
        if Not_Sync then
        
            if GetStoredBoolean(Cache, "p", "0") then
                call StoreBoolean(Cache, "p", "0", FALSE)
                set Space_Player = Player(0)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "1") then
                call StoreBoolean(Cache, "p", "1", FALSE)
                set Space_Player = Player(1)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "2") then
                call StoreBoolean(Cache, "p", "2", FALSE)
                set Space_Player = Player(2)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "3") then
                call StoreBoolean(Cache, "p", "3", FALSE)
                set Space_Player = Player(3)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "4") then
                call StoreBoolean(Cache, "p", "4", FALSE)
                set Space_Player = Player(4)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "5") then
                call StoreBoolean(Cache, "p", "5", FALSE)
                set Space_Player = Player(5)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "6") then
                call StoreBoolean(Cache, "p", "6", FALSE)
                set Space_Player = Player(6)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "7") then
                call StoreBoolean(Cache, "p", "7", FALSE)
                set Space_Player = Player(7)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "8") then
                call StoreBoolean(Cache, "p", "8", FALSE)
                set Space_Player = Player(8)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "9") then
                call StoreBoolean(Cache, "p", "9", FALSE)
                set Space_Player = Player(9)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "a") then
                call StoreBoolean(Cache, "p", "a", FALSE)
                set Space_Player = Player(10)
                call TriggerEvaluate(Space_Actions)
            endif
            if GetStoredBoolean(Cache, "p", "b") then
                call StoreBoolean(Cache, "p", "b", FALSE)
                set Space_Player = Player(11)
                call TriggerEvaluate(Space_Actions)
            endif
            
            set Not_Sync = FALSE
            //call TriggerSyncStart()
        
            if ((x == Space_X) and (y == Space_Y)) then
                call StoreBoolean(Cache, "p", Local_S, TRUE)
            else
                set Space_X = x
                call StoreBoolean(Cache, "p", Local_S, FALSE)
            endif
            set Space_Y = (y + 0.01)
            call SetCameraQuickPosition(Space_X, Space_Y)
        
            call SyncStoredBoolean(Cache, "p", Local_S)
            call TriggerSyncReady()
        
            set Not_Sync = TRUE
        endif
    endfunction


    private function Init takes nothing returns nothing
    
        call FlushGameCache(InitGameCache("s"))
        set Cache = InitGameCache("s")
       
        set Local_I = GetPlayerId(GetLocalPlayer())
        set Local_S = SubString("0123456789abcdef", Local_I, Local_I + 1)
    
    
        call TimerStart(Space_Timer, 0.1250, true, function Handler)
    endfunction

endlibrary

Testing trigger for multiplayer.

JASS:
library SpaceHandlerTester initializer Init requires SpaceHandler
   
    private function SpacePressed takes nothing returns nothing
        local player p = GetSpacePlayer() // This function must be called only 1 time
        
        
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 3.0, "Spacebar is pressed by: " + GetPlayerName(p))
        //call UnitApplyTimedLife(CreateUnit(p, 'hwat', -1000, -500, 0.0), 'BHwe', 3.0) // this causes desync
       
    endfunction
   
    private function Init takes nothing returns nothing
       
        call AddSpacebarAction(function SpacePressed)
       
    endfunction
   
endlibrary
 

Attachments

  • spacebar.w3x
    18.2 KB · Views: 216
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
Even if the user don't change the "camera quick position" by trigger, there are still plenty of things hardcoded in the game which will change it, like when an unit is attacked.

More, when wc3 is minimized, cameras are hold, the target position X/Y keep the same values.

Finally since camera positions are something local by nature, i'm not sure it's safe to use it like that.
Indeed, i don't think that camera positions for each player are synced.
Ofc displaying a text message is fine, but not creating/destroying handles and so one.
 
Level 18
Joined
Oct 20, 2007
Messages
353
Even if the user don't change the "camera quick position" by trigger, there are still plenty of things hardcoded in the game which will change it, like when an unit is attacked.

More, when wc3 is minimized, cameras are hold, the target position X/Y keep the same values.

Finally since camera positions are something local by nature, i'm not sure it's safe to use it like that.
Indeed, i don't think that camera positions for each player are synced.
Ofc displaying a text message is fine, but not creating/destroying handles and so one.

For me, when unit is attacked space-bar point don't changes. Are you sure that it does?

Situation when Wc3 is minimized and spacebar is pressed at one time, I think are rare.

Oh, I have forgotten about that desyncs. In next version I'll add synchronization.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
For me, when unit is attacked space-bar point don't changes. Are you sure that it does?

Well, i don't remember that much, but when your base is attacked, an unit finished to be trained, some things like that.

Situation when Wc3 is minimized and spacebar is pressed at one time, I think are rare.

In fact there is no chance, a player can't interact while his wc3 is minimized.
It was just a quick thought since you play with camera positions, but there is no problem since y will still never be equal to spacey.

Oh, I have forgotten about that desyncs. In next version I'll add synchronization.

Regardless you will use game cache and sync natives functions or a local select unit event, it will be horribly delayed. (much more than 0.1 s)
Even in a lan game.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
If i believe this post that's not a good idea to use sync natives together with TSA.

Anyway i'm sure TSA is useless, as the sync natives already act as a wait.

Also 0.1 is a too much optimist value, as the sync time would be several times slower.
Maybe , 0.5 s.
 
Last edited:
Level 18
Joined
Oct 20, 2007
Messages
353
If i believe this post that's not a good idea to use sync natives together with TSA.

Anyway i'm sure TSA is useless, as the sync natives already act as a wait.

Also 0.1 is a too much optimist value, as the sync time would be several times slower.
Maybe , 0.5 s.

Thanks for that link! I have updated the code, but haven't tested it yet.

Troll-Brain, can you test it please? I can't test it myself. If you deny, I won't be angry at you).
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I can't host.

Instead of a loop to sync each local data, i suppose that would work :

JASS:
library SpaceHandler initializer Init // by D.O.G. version 2.0
    
    globals
        //public real                 SyncTime = 0.09 // Can be changed during game
        private constant real CHECK_SPACE_TIME = 0.5 // Can't be changed during game
    endglobals
    
    //=================================================
    // This function is called when spacebar is pressed
    //=================================================
    // * Instead of using "GetTriggerPlayer()" use
    // function parameter "trig_player"
    // * Use "camera_x" and "camera_y" to get triggering
    // player's camera target coordinates
    private function SpacePressed takes player trig_player, real camera_x, real camera_y returns nothing
        
        call DisplayTimedTextFromPlayer(trig_player, 10.00, "Spacebar is pressed by: " + "%s")
        // i love DisplayTimedTextFromPlayer, since using DisplayTimedTextToPlayer together with GetLocalPlayer will bug on replays
        call UnitApplyTimedLife(CreateUnit(trig_player, 'hwat', camera_x, camera_y, 0.0), 'BHwe', 10.0)
        
    endfunction
    //=================================================
    
    
    globals
        private integer Local_pi //= GetPlayerId(GetLocalPlayer())
        private string Local_s // I2S(Local_pi)
        private real array Space_x
        private real array Space_y
        private gamecache Cache
    endglobals
    
    private function Actions takes nothing returns nothing
        local real x
        local real y
        local integer i = 0
   
        // i'm not sure for these block of lines but that should work
        call StoreReal(Cache, "space_x", Local_s, GetCameraTargetPositionX())
        call StoreReal(Cache, "space_y", Local_s, GetCameraTargetPositionY())
        call SyncStoredReal(Cache,"space_x",Local_s)
        call SyncStoredReal(Cache,"space_y",Local_s)
   
        call TriggerSyncReady()
        
        set i = 0
        loop
        exitwhen i == 12
            set x = GetStoredReal(Cache, "space_x", I2S(i))
            set y = GetStoredReal(Cache, "space_y", I2S(i))
            if ((x == Space_x[i]) and (y == Space_y[i])) then
                call SpacePressed(Player(i), x, y)
            else
                set Space_x[i] = x
            endif
            set Space_y[i] = (y + 0.01)
      
        set i = i + 1
        endloop
        call SetCameraQuickPosition(Space_x[Local_pi], Space_y[Local_pi]) // 100 % sure it will work
    endfunction
    
    
    private function Init takes nothing returns nothing
        local integer i = 0
        local trigger trig = CreateTrigger()
     
        call FlushGameCache(InitGameCache("SpaceHandler"))
        Cache = InitGameCache("SpaceHandler")
        // since if there is already a saved game cache called "SpaceHandler" in the current player profile (unlikeky, sure, but meh)
        // [url]http://www.hiveworkshop.com/forums/triggers-scripts-269/game-cache-initialization-213729/[/url]
        set Local_pi = GetPlayerId(GetLocalPlayer())
        set Local_s = I2S(Local_pi)
        loop
            exitwhen i == 12
            set Space_x[i] = 1000000000.0
            set Space_y[i] = 1000000000.0
            set i = i + 1
        endloop
        call TriggerRegisterTimerEvent(trig, CHECK_SPACE_TIME, true)
        call TriggerAddAction(trig, function Actions)
    endfunction
    
endlibrary

Read the comments, note that i've edited the code in jasscraft, there are no checks.

Also i've used a better naming convention (for me).
The only thing you could really argue is for global variables, but for me functions and variables names should be really different, so that wouldn't be a problem.
One day my personal jass naming convention will conquer the world (or not)
 
Last edited:
Level 18
Joined
Oct 20, 2007
Messages
353
I can't host.

Instead of a loop to sync each local data, i suppose that would work :

JASS:
library SpaceHandler initializer Init // by D.O.G. version 2.0
    
    globals
        //public real                 SyncTime = 0.09 // Can be changed during game
        private constant real CHECK_SPACE_TIME = 0.5 // Can't be changed during game
    endglobals
    
    //=================================================
    // This function is called when spacebar is pressed
    //=================================================
    // * Instead of using "GetTriggerPlayer()" use
    // function parameter "trig_player"
    // * Use "camera_x" and "camera_y" to get triggering
    // player's camera target coordinates
    private function SpacePressed takes player trig_player, real camera_x, real camera_y returns nothing
        
        call DisplayTimedTextFromPlayer(trig_player, 10.00, "Spacebar is pressed by: " + "%s")
        // i love DisplayTimedTextFromPlayer, since using DisplayTimedTextToPlayer together with GetLocalPlayer will bug on replays
        call UnitApplyTimedLife(CreateUnit(trig_player, 'hwat', camera_x, camera_y, 0.0), 'BHwe', 10.0)
        
    endfunction
    //=================================================
    
    
    globals
        private integer Local_pi //= GetPlayerId(GetLocalPlayer())
        private string Local_s // I2S(Local_pi)
        private real array Space_x
        private real array Space_y
        private gamecache Cache
    endglobals
    
    private function Actions takes nothing returns nothing
        local real x
        local real y
        local integer i = 0
   
        // i'm not sure for these block of lines but that should work
        call StoreReal(Cache, "space_x", Local_s, GetCameraTargetPositionX())
        call StoreReal(Cache, "space_y", Local_s, GetCameraTargetPositionY())
        call SyncStoredReal(Cache,"space_x",Local_s)
        call SyncStoredReal(Cache,"space_y",Local_s)
   
        call TriggerSyncReady()
        
        set i = 0
        loop
        exitwhen i == 12
            set x = GetStoredReal(Cache, "space_x", I2S(i))
            set y = GetStoredReal(Cache, "space_y", I2S(i))
            if ((x == Space_x[i]) and (y == Space_y[i])) then
                call SpacePressed(Player(i), x, y)
            else
                set Space_x[i] = x
            endif
            set Space_y[i] = (y + 0.01)
      
        set i = i + 1
        endloop
        call SetCameraQuickPosition(Space_x[Local_pi], Space_y[Local_pi]) // 100 % sure it will work
    endfunction
    
    
    private function Init takes nothing returns nothing
        local integer i = 0
        local trigger trig = CreateTrigger()
     
        call FlushGameCache(InitGameCache("SpaceHandler"))
        Cache = InitGameCache("SpaceHandler")
        // since if there is already a saved game cache called "SpaceHandler" in the current player profile (unlikeky, sure, but meh)
        // [url]http://www.hiveworkshop.com/forums/triggers-scripts-269/game-cache-initialization-213729/[/url]
        set Local_pi = GetPlayerId(GetLocalPlayer())
        set Local_s = I2S(Local_pi)
        loop
            exitwhen i == 12
            set Space_x[i] = 1000000000.0
            set Space_y[i] = 1000000000.0
            set i = i + 1
        endloop
        call TriggerRegisterTimerEvent(trig, CHECK_SPACE_TIME, true)
        call TriggerAddAction(trig, function Actions)
    endfunction
    
endlibrary

Read the comments, note that i've edited the code in jasscraft, there are no checks.

Also i've used a better naming convention (for me).
The only thing you could really argue is for global variables, but for me functions and variables names should be really different, so that wouldn't be a problem.
One day my personal jass naming convention will conquer the world (or not)

Thanks for big code improvement. I tested in single player mode - it worked. But in multiplayer I can't.

Updated snippet.


EDIT:

I tryed to test code. The results:

When I have pressed spacebar, message was shown and unit was created - and there wasn't any desync - second player resumed to play.
When he presses spacebar, message was shown and immediately after it he left game. I don't know if himself left or it was desync.
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
I'm wondering what happens if the sync time is > CHECK_SPACE_TIME.

For safety, you should handle a boolean variable and avoid an other sync if one is currently under process.
Or you could even change the timer period dynamically, according to the sync time measured (not sure that's really a good idea)

In you script you lack a "set" :

JASS:
set Cache = InitGameCache("SpaceHandler")

Talking about the jass naming convention, i use This_syntax for a global variable and this_one for a local variable, just because i hate use a prefix for a global variable such as "udg_", or "g_", coz it makes short common names ugly, such as "N".
It's totally a matter of taste, and some people could say it's an ugly convention.
But for sure either use mine, or the more common, or something else, but there is no point to use This_Syntax for a local variable.
Also, note that i use This_syntax and not This_Syntax for a global variable, again it's to make a bigger difference with function names.

Now, ofc again it's just a matter of opinion, i just like to spread my personal convention.

According to your edit, you need an other test, if it doesn't work, i suppose you would back to the loop sync.
 
Level 18
Joined
Oct 20, 2007
Messages
353
In you script you lack a "set" :

JASS:
set Cache = InitGameCache("SpaceHandler")

That's in your script, not in my.

I'm wondering what happens if the sync time is > CHECK_SPACE_TIME.

For safety, you should handle a boolean variable and avoid an other sync if one is currently under process.

Good idea, I will try.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
More comments are needed if you set it to 0.1, because users would expect to be more accurate than it is.

Also, i suppose a GetLastTimeSync function wouldn't hurt.

Finally instead of the SpacePressed function it would be better to use a function interface or a custom function with a code argument.
I agree that it is a very specifical use, but "hardcoding" a stuff in a needed library is not a good practice.

Or just use the Event library, as it is afterall a custom event.
 
Level 18
Joined
Oct 20, 2007
Messages
353
More comments are needed if you set it to 0.1, because users would expect to be more accurate than it is.

Also, i suppose a GetLastTimeSync function wouldn't hurt.

Finally instead of the SpacePressed function it would be better to use a function interface or a custom function with a code argument.
I agree that it is a very specifical use, but "hardcoding" a stuff in a needed library is not a good practice.

Or just use the Event library, as it is afterall a custom event.

Can tell me how to do custom events?

Anyway, code even with checking for sync doesn't work in multiplayer. I don't have any idea...
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Can tell me how to do custom events?

Anyway, code even with checking for sync doesn't work in multiplayer. I don't have any idea...

I suppose there are some libraries here which use the library Event.
You could take them as an example.

It doesn't work, even with the boolean ?
How it doesn't work btw ?

You could also back to the loop sync (first block of code), because as said i'm not 100 % sure it will work even if it should.

And finally the guy who wrote about the sync stuff could be wrong.
 
This is coded wrong. When you use spacebar, the player's window goes to that player's start location, not to some point off the screen.


GetStartLocationX(GetPlayerId(GetLocalPlayer())) == GetCameraTargetPositionX() and GetStartLocationY(GetPlayerId(GetLocalPlayer())) == GetCameraTargetPositionY()

It's a quick fix ; ).

Also, be sure to start the start location coords in vars to improve speed and readability a bit ^_^.
JASS:
set x = GetStartLocationX(GetPlayerId(GetLocalPlayer()))
set y = GetStartLocationY(GetPlayerId(GetLocalPlayer()))


Nice attempt for one of your first resources, gj ^)^. +rep.


Be sure to use the Event library for your custom events ; ).


This is the main thing you have to watch out for -> http://www.hiveworkshop.com/forums/jass-ai-scripts-tutorials-280/custom-event-data-187478/
 
Ah, my bad =). I've never used that native, so I wasn't sure what it did ;p.

I just knew from experience that spacebar auto returns u to player start locations ^)^


Then all this needs is the event stuff and it's good to go =D.


Spacebar event will be a very useful event to have. It's too bad that it's local only for the moment.

edit
make this use timeout of .031250000 for more accurate event responses please =O. As such, please make this use CTL so that it's merged with other timers of that timeout =). All you need to do is make a TimerGroup ^_^.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
@D.O.G :

Don't worry using CTL will never be a requirement for that. (In case you don't like/understand the API)
Using one timer for that is enough fine here.
Plus i'm not sure that even in a single player game cameras are that fast.
 
Level 18
Joined
Oct 20, 2007
Messages
353
So StoreReal with GetLocalPlayer doesn't work, you have to do a loop ?
That doesn't really make sense, because with or without the loop it's already used in a local block for each player.

Or have you done it just to be sure ?

I've made it to be sure. I have tested - current version (4.0) works 100% with 2 players (must work with more players).

EDIT: I've added untested version without loops. Hopefully, I could test it tonight.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Actually i meant without TSA and TriggerSyncStart together, instead of TriggerSyncStart + TSA. (still about the linked thread i gave)
However, you're probably bored to do tests :p
But this one is quite important, the TSA is lame.
Btw you should use a timer instead.

Also instead of leave SpacePressed "hardcoded" in the library, you should use a function interface, or the library Event.
Else, you can't make it as a requirement in a public resource.
 
Last edited:
Level 18
Joined
Oct 20, 2007
Messages
353
Actually i meant without TSA and TriggerSyncStart together, instead of TriggerSyncStart + TSA. (still about the linked thread i gave)
However, you're probably bored to do tests :p
But this one is quite important, the TSA is lame.
Btw you should use a timer instead.

Also instead of leave SpacePressed "hardcoded" in the library, you should use a function interface, or the library Event.
Else, you can't make it as a requirement in a public resource.

I just realized that it works without TSA and TriggerSyncStart, but not always, if you press spacebar many times one after another it causes desync. Will try make longer timer timeout.

Btw, why timer is better than perioddic event? One time I tryed timer - it was inaccurate.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Timers are halt when the game is paused, which is not the case for TSA.
And actually it's TSA which is innacurate and "random" with the same value, not timers.

Also it's strange that it desync, as with the boolean two sync are not supposed to happen in the same time.

Try with a timer instead of TSA, and check what happens.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
TriggerClearActions doesn't deallocate memory used by the trigger actions, it just deactivate them, TriggerRemoveAction work as expected, but then you have to link trigger actions and the trigger.

There is no problem with TriggerClearCondition, and in fact you don't have even to call it if you plan to destroy a trigger.
So you could simply use trigger conditions, you can even use a function that takes and returns nothing (even if pjass won't allow that so easily, but if the argument is a code it won't cry).
Also, for some reasons triggers conditions are faster than trigger actions and still open a new thread, but the script efficiency is not a problem here anyway, it's just a plus, it's not like you can hit the spacebar 100 times per second.
 
Level 18
Joined
Oct 20, 2007
Messages
353
... you can even use a function that takes and returns nothing ...

Really? I used actions only because with conditions it asks for returning boolean. Will change to conditions.

... it's not like you can hit the spacebar 100 times per second.

Challenge accepted! =)

EDIT: Updated.
 
The snippets won't compile at the moment.
If you pass a code that returns nothing to a function that inlines, it will return an error telling you that functions passed to Condition/Filter need to return a boolean.
The fix is to just add an extra redundant line at the end of those functions.
Just add return to the end of the AddXXAction functions :p

Oh, and you could use Filter instead of Condition because it has a shorter name, so it's faster =p (And it gives you the same results)
 
Level 18
Joined
Oct 20, 2007
Messages
353
The snippets won't compile at the moment.
If you pass a code that returns nothing to a function that inlines, it will return an error telling you that functions passed to Condition/Filter need to return a boolean.
The fix is to just add an extra redundant line at the end of those functions.
Just add return to the end of the AddXXAction functions :p

Oh, and you could use Filter instead of Condition because it has a shorter name, so it's faster =p (And it gives you the same results)

Snippets compile - I have tested them.

And in which function add return - AddSpacebarAction or SpacePressed ?
In AddSpacebarAction there already is return.
 
Last edited:
JASS:
library SpaceHandlerLocalTester initializer Init requires SpaceHandlerLocal
    
    private function SpacePressed takes nothing returns nothing
        local player p = GetLocalPlayer() 
        call DisplayTimedTextFromPlayer(p, 0.0, 0.0, 10.0, "Spacebar is pressed by: %s")
        
    endfunction
    
    private function Init takes nothing returns nothing
        
        call AddSpacebarAction(function SpacePressed)
        
    endfunction
    
endlibrary

This doesn't compile with my JassHelper because function must return boolean (you're either in debug mode or you changed your JassHelper.config to not inline, or you are using a modified pJass which skips this error).

Like Mag said, you can add a "return" to the "TriggerAddCondition" function. Also removing a trigger condition flat-out is not a good idea because it will crash the trigger from finishing its evaluation for any remaining conditions.
 
attachment.php


Test Code

JASS:
library Demo requires SpaceHandler

    function Exec takes nothing returns nothing
    endfunction

    private struct Inits extends array
        private static method onInit takes nothing returns nothing
            call AddSpacebarAction(function Exec)
        endmethod
    endstruct

endlibrary

edit
Oh lol, Bribe beat me to it by a few seconds :p
 

Attachments

  • Stupid fucks.PNG
    Stupid fucks.PNG
    231.1 KB · Views: 253
Do you guys think this is worth submitting as a resource?

JASS:
library TriggerCondition
    
    globals
        private trigger array trigs
        private triggercondition array conditions
        private integer stack = -1
    endglobals
    
    private function Remove takes nothing returns nothing
        call DestroyTimer(GetExpiredTimer())
        loop
            call TriggerRemoveCondition(trigs[stack], conditions[stack])
            set trigs[stack] = null
            set conditions[stack] = null
            set stack = stack - 1
            exitwhen stack < 0
        endloop
    endfunction
    
    function TriggerRemoveConditionSafe takes trigger t, triggercondition c returns nothing
        set stack = stack + 1
        set trigs[stack] = t
        set conditions[stack] = c
        if stack == 0 then
            call TimerStart(CreateTimer(), 0., false, function Remove)
        endif
    endfunction
    
    function TriggerAddConditionBJ takes trigger t, code c returns triggercondition
        return TriggerAddCondition(t, Filter(c))
        return null
    endfunction
    
endlibrary
 
Last edited:
Level 18
Joined
Oct 20, 2007
Messages
353
You guys want I put return here?

JASS:
library SpaceHandlerLocalTester initializer Init requires SpaceHandlerLocal
    
    private function SpacePressed takes nothing returns boolean
        local player p = GetLocalPlayer() 
        call DisplayTimedTextFromPlayer(p, 0.0, 0.0, 10.0, "Spacebar is pressed by: %s")
        return false
    endfunction
    
    private function Init takes nothing returns nothing
        
        call AddSpacebarAction(function SpacePressed)
        
    endfunction
    
endlibrary
 
Top