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

[JASS] Global functions

Status
Not open for further replies.
Level 2
Joined
Jul 7, 2010
Messages
7
Hello,

I'd like to know if there's a way to create "global functions". That means functions, which are accessible in all triggers.

Here's my particular problem:

I made a function GetColoredPlayerName inside the trigger PlayerDies (For the typical "WorldEdit has been killed by creeps!" message). Then I started working on HeroSelect trigger and decided to use the same GetColoredPlayerName function for the message "WorldEdit has chosen a Paladin.". There's no doubt there will be more opportunities to use this function.

When I call the function GetColoredPlayerName inside another trigger (means not the trigger where it's declared) it results in error: Expected a name.

I'd like find an effective solution. I'm trying to find a way to enable using one function among all triggers.
 
There's a few options.

  1. Download JNGP and JassHelper. This will allow you to utilize scopes and libraries which place your code at the top of your script, allowing other pieces of code to use them. This is the most preferred option.
  2. In your trigger editor there should be a little map icon with your maps name on the left column (where your trigger names / categories are). Click that and write JASS code in there, and your other triggers can use those functions.
  3. Edit your war3map.j manually.
 
Level 2
Joined
Jul 7, 2010
Messages
7
I like the 3rd option. I've tried to cut the function from the trigger and place it at the very top of war3map.j but it doesn't work. It still results in error: Expected a name. Where exactly should I place the function inside war3map.j?
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Every function declared in JASS is global, and can be referenced from any script that is below the declaration of said function. There is an exception to this when using ExecuteFunc which allows you to run functions that aren't visible due to it being executed at run-time, rather than before-hand. Note that this function can also cause Warcraft III to crash.

I'd like find an effective solution. I'm trying to find a way to enable using one function among all triggers.

The most effective solution, as TriggerHappy has outlined, is to download JNGP; it provides an advanced syntax that allows easier transportation of code from map-to-map as well as easier implementation of scripts that are built upon other scripts, or systems, etc.

This allows you to declare a library which can be used to organize your code flawlessly, or declare a scope which is basically a low-priority library that cannot be organized; typically these are all independent of each other, libraries should contain code that is implemented in various scopes.
 
Level 2
Joined
Jul 7, 2010
Messages
7
Every function declared in JASS is global, and can be referenced from any script that is below the declaration of said function.

I've checked my war3map.j and the function GetColoredPlayerName is the very first function in the trigger section (And it's inside the very first trigger in Trigger editor).

That means every time I call the function, the calling script is below the function declaration. However, every time I call the function from any other trigger, it results in 1 complile error: Name expected. So where's the flaw?

P.S: The map is a RoC one (with *.w3m extension), I hope it's not a expansion dependant issue.
 
Level 2
Joined
Jul 7, 2010
Messages
7
The very first trigger:

  • PlayerDies
JASS:
// Returns colored player name string

function GetPlayerNameColored takes player p returns string
    local playercolor col=GetPlayerColor(p)
    local string r=GetPlayerName(p)
    if col == PLAYER_COLOR_RED then
        set r = "|CFFFF0303" + r + "|r"
    elseif col == PLAYER_COLOR_BLUE then
        set r = "|CFF0042FF" + r + "|r"
    elseif col == PLAYER_COLOR_CYAN then
        set r = "|CFF1CE6B9" + r + "|r"
    elseif col == PLAYER_COLOR_PURPLE then
        set r = "|CFF540081" + r + "|r"
    elseif col == PLAYER_COLOR_YELLOW then
        set r = "|CFFFFFC00" + r + "|r"
    elseif col == PLAYER_COLOR_ORANGE then
        set r = "|CFFFE8A0E" + r + "|r"
    elseif col == PLAYER_COLOR_GREEN then
        set r = "|CFF20C000" + r + "|r"
    elseif col == PLAYER_COLOR_PINK then
        set r = "|cffff80c0" + r + "|r"
    elseif col == PLAYER_COLOR_LIGHT_GRAY then
        set r = "|CFF959697" + r + "|r"
    elseif col == PLAYER_COLOR_LIGHT_BLUE then
        set r = "|CFF7FBFF1" + r + "|r"
    elseif col == PLAYER_COLOR_AQUA then
        set r = "|CFF106246" + r + "|r"
    elseif col == PLAYER_COLOR_BROWN then
        set r = "|CFF492A04" + r + "|r"
    else
        set r = ""
    endif
    set col = null
    return r
endfunction


// Revives a hero either in Light or Dark base

function ReviveHeroInBase takes unit u, player p returns nothing
    // Light Hero
    if ( IsUnitAlly(u, Player(5)) == true ) then
        call CameraSetupApplyForPlayer( true, gg_cam_Camera_001, p, 1.00 )
        call ReviveHeroLoc( u, GetRectCenter(gg_rct_Region_012), true )
    // Dark Hero
    else
        call CameraSetupApplyForPlayer( true, gg_cam_Camera_002, p, 1.00 )
        call ReviveHeroLoc( u, GetRectCenter(gg_rct_Region_013), true )
    endif
endfunction



// If triggering unit is a hero

function Trig_PlayerDies_Conditions takes nothing returns boolean
    if ( IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == false ) then
        return false
    endif
    return true
endfunction



// Display message and make neccessary steps

function Trig_PlayerDies_Actions takes nothing returns nothing

    // Hero has been teamkilled
    if ( IsUnitAlly(GetKillingUnitBJ(), GetOwningPlayer(GetDyingUnit())) == true ) then
        call DisplayTextToForce( GetPlayersAll(), ( GetPlayerNameColored(GetTriggerPlayer()) + ( " has been teamkilled by " + GetPlayerNameColored(GetOwningPlayer(GetKillingUnitBJ())) + "!" ) ) )
        call ReviveHeroInBase(GetDyingUnit(), GetTriggerPlayer())

    // Hero has been creepkilled
    elseif ( GetOwningPlayer(GetKillingUnitBJ()) == Player(12) ) then
        call DisplayTextToForce( GetPlayersAll(), ( GetPlayerNameColored(GetTriggerPlayer()) + ( " has been killed by " + GetUnitName(GetKillingUnitBJ())) + "!" ) )
        call AdjustPlayerStateBJ( ( -100 - ( GetUnitLevel(GetDyingUnit()) * 50 ) ), GetOwningPlayer(GetDyingUnit()), PLAYER_STATE_RESOURCE_GOLD )
        call DisplayTextToForce( GetPlayersAll(), ( GetPlayerNameColored(GetTriggerPlayer()) + ( " has been killed by " + GetPlayerNameColored(GetOwningPlayer(GetKillingUnitBJ())) + "!" ) ) )
        call StartTimerBJ( udg_Timer1, false, I2R(( GetUnitLevel(GetDyingUnit()) * 10 )) )
        call CreateTimerDialogBJ( GetLastCreatedTimerBJ(), GetPlayerNameColored(GetTriggerPlayer()) )
        call TriggerSleepAction( ( I2R(GetUnitLevel(GetDyingUnit())) * 10.00 ) )
        call DestroyTimerDialogBJ( GetLastCreatedTimerDialogBJ() )
        call ReviveHeroInBase(GetDyingUnit(), GetTriggerPlayer())

    // Hero has been killed by enemy forces
    else
        call AdjustPlayerStateBJ( ( 200 + ( GetUnitLevel(GetDyingUnit()) * 50 ) ), GetOwningPlayer(GetKillingUnitBJ()), PLAYER_STATE_RESOURCE_GOLD )
        call AdjustPlayerStateBJ( ( -100 - ( GetUnitLevel(GetDyingUnit()) * 50 ) ), GetOwningPlayer(GetDyingUnit()), PLAYER_STATE_RESOURCE_GOLD )
        call DisplayTextToForce( GetPlayersAll(), ( GetPlayerNameColored(GetTriggerPlayer()) + ( " has been killed by " + GetPlayerNameColored(GetOwningPlayer(GetKillingUnitBJ())) + "!" ) ) )
        call StartTimerBJ( udg_Timer1, false, I2R(( GetUnitLevel(GetDyingUnit()) * 10 )) )
        call CreateTimerDialogBJ( GetLastCreatedTimerBJ(), GetPlayerNameColored(GetTriggerPlayer()) )
        call TriggerSleepAction( ( I2R(GetUnitLevel(GetDyingUnit())) * 10.00 ) )
        call DestroyTimerDialogBJ( GetLastCreatedTimerDialogBJ() )
        call ReviveHeroInBase(GetDyingUnit(), GetTriggerPlayer())
    endif

endfunction



//===========================================================================

function InitTrig_PlayerDies takes nothing returns nothing
    set gg_trg_PlayerDies = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_PlayerDies, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_PlayerDies, Condition( function Trig_PlayerDies_Conditions ) )
    call TriggerAddAction( gg_trg_PlayerDies, function Trig_PlayerDies_Actions )
endfunction

Second trigger (using function GetPlayerNameColored from 1st trigger):

  • HeroPaladin
JASS:
function Trig_HeroPaladin_Actions takes nothing returns nothing
    call CameraSetupApplyForPlayer( true, gg_cam_Camera_001, GetOwningPlayer(GetTriggerUnit()), 1.00 )
    call CreateNUnitsAtLoc( 1, 'Hpal', GetOwningPlayer(GetTriggerUnit()), GetRectCenter(gg_rct_Region_012), 45.00 )
    call DisplayTimedTextToForce( GetPlayersAllies(Player(5)), 3.00, ( GetPlayerNameColored(GetTriggerPlayer()) + " has chosen a Paladin." ) )
    call RemoveUnit( GetTriggerUnit() )
endfunction

//===========================================================================
function InitTrig_HeroPaladin takes nothing returns nothing
    set gg_trg_HeroPaladin = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_HeroPaladin, gg_rct_Region_000 )
    call TriggerAddAction( gg_trg_HeroPaladin, function Trig_HeroPaladin_Actions )
endfunction

Both triggers are in the same category.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
I have no problem putting your triggers into a blank map, it must have something to do with the fact that you're using the Reign of Chaos edition of Warcraft III; there may not be a lot of features that we assume here.
 
Status
Not open for further replies.
Top