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

[JASS] Is there somewhere I'm using locals improperly?

Status
Not open for further replies.
Level 13
Joined
Jul 26, 2008
Messages
1,009
Alright I have a little color minigame in my map. Basically when you buy this item It's removed, and a minigame starts where you have to guess what color the fog tint is by typing it's name real fast.

Well the game tends to desync players on occasion. I can't exactly see where I'm using the GetLocalPlayer incorrectly, and was hoping someone could tell me, as I haven't learned much past basics with them. Thanks.

JASS:
scope ColorGame initializer init

globals
    private trigger array GAME
    private integer array COUNTED
    private string array COLOR
    private real array X
    private real array Y
    hashtable CG
endglobals

private function Color takes nothing returns boolean
 local integer id = GetPlayerId(GetTriggerPlayer())
 local string str = "x"
    set str = " "
    call DestroyTextTag(TALKTAG[id])
    set TALKTAG[id] = CreateTextTag()
    if GetEventPlayerChatString() == COLOR[id] then
        set COUNTED[id] = COUNTED[id] + 1
        if GetLocalPlayer() == Player(id) and COUNTED[id] > 7 then
            call ResetTerrainFog()
            set str = "You've won!
    +10 |cffff0000Blood|r"
        elseif GetLocalPlayer() == Player(id) then
            call ResetTerrainFog()
            set str = "Correct!"
        endif
        if COUNTED[id] > 7 then
            call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD) + 10 )
            set IsGaming[id] = false
        else
            set PLAYER = Player(id)
            call ExecuteFunc("ColorGame_Begin")
        endif
    else
        if GetLocalPlayer() == Player(id) then
            call ResetTerrainFog()
            set str = "You lost. The correct color was " + COLOR[id] + ". Try again!"
            set IsGaming[id] = false
        endif
    endif
    call SetTextTagText(TALKTAG[id], str, 0.024)
    call SetTextTagPos(TALKTAG[id], X[id], Y[id], 0.00)
    call SetTextTagColor(TALKTAG[id], GetPlayerTagColor(Player(id), "red"), GetPlayerTagColor(Player(id), "green"), GetPlayerTagColor(Player(id), "blue"), 255)
    call SetTextTagVisibility(TALKTAG[id], true)
    call SetTextTagFadepoint(TALKTAG[id], 2)
    call SetTextTagLifespan(TALKTAG[id], 2.5)
    call SetTextTagPermanent(TALKTAG[id], false)
    call DestroyTrigger(GAME[id])
    set GAME[id] = null
 return false
endfunction

private function Timer takes nothing returns nothing
 local player p = LoadPlayerHandle(CG, GetHandleId(GetExpiredTimer()), 0)
 local integer id = GetPlayerId(p)
    if GAME[id] != null then
        call DestroyTrigger(GAME[id])
        set GAME[id] = null
        set IsGaming[id] = false
        call DisplayTextToPlayer(p, 0, 0, "You lose! Gotta be faster than that.")
        if GetLocalPlayer() == p then
            call ResetTerrainFog()
        endif
    endif
    call PauseTimer(GetExpiredTimer())
    call DestroyTimer(GetExpiredTimer())
 set p = null
endfunction

function ColorGame_Begin takes nothing returns nothing
 local integer id = GetPlayerId(PLAYER)
 local integer i = GetRandomInt(1,6)
 local timer tim
    call TriggerSleepAction(3)
    set GAME[id] = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(GAME[id], Player(id), "", false)
    if i == 1 then
        if GetLocalPlayer() == Player(id) then
            call SetTerrainFogEx(1, 500, 1000, 0.5, 1, 0, 0)
        endif
        set COLOR[id] = "red"
    elseif i == 2 then
        if GetLocalPlayer() == Player(id) then
            call SetTerrainFogEx(1, 500, 1000, 0.5, 0, 1, 0)
        endif
        set COLOR[id] = "green"
    elseif i == 3 then
        if GetLocalPlayer() == Player(id) then
            call SetTerrainFogEx(1, 500, 1000, 0.5, 0, 0, 1)
        endif
        set COLOR[id] = "blue"
    elseif i == 4 then
        if GetLocalPlayer() == Player(id) then
            call SetTerrainFogEx(1, 500, 1000, 0.5, 1, 1, 0)
        endif
        set COLOR[id] = "yellow"
    elseif i == 5 then
        if GetLocalPlayer() == Player(id) then
            call SetTerrainFogEx(1, 500, 1000, 0.5, .5, 0, .5)
        endif
        set COLOR[id] = "purple"
    elseif i == 6 then
        if GetLocalPlayer() == Player(id) then
            call SetTerrainFogEx(1, 500, 1000, 0.5, 1, .5, 0)
        endif
        set COLOR[id] = "orange"
    endif
    call TriggerAddCondition(GAME[id], function Color)
    set tim = CreateTimer()
    call SavePlayerHandle(CG, GetHandleId(tim), 0, Player(id))
    call TimerStart(tim, 0.65+StringLength(COLOR[id])*GetRandomReal(0.2,0.3), false, function Timer)
    set tim = null
endfunction

private function RemoveIt takes nothing returns boolean
 local integer id = GetPlayerId(GetOwningPlayer(GetBuyingUnit()))
 local unit c = GetTriggerUnit()
 local string str = " "
    if GetItemTypeId(GetSoldItem()) == 'Mctg' and not IsGaming[id] then
        call DestroyTextTag(TALKTAG[id])
        set TALKTAG[id] = CreateTextTag()
        set X[id] = GetUnitX(c)
        set Y[id] = GetUnitY(c)
        set COUNTED[id] = 0
        if GetLocalPlayer() == Player(id) then
            set str = "You'll have a timelimit to enter in the name of colors as they appear on your screen. Get ready, the game starts in 3 seconds."
        endif
        call RemoveItem(GetSoldItem())
        call AddItemToStock(c, 'Mctg', 1, 1)
        set IsGaming[id] = true
        set PLAYER = Player(id)
        call ExecuteFunc("ColorGame_Begin")
        call SetTextTagText(TALKTAG[id], str, 0.024)
        call SetTextTagPos(TALKTAG[id], GetUnitX(c), GetUnitY(c), 0.00)
        call SetTextTagColor(TALKTAG[id], GetPlayerTagColor(Player(id), "red"), GetPlayerTagColor(Player(id), "blue"), GetPlayerTagColor(Player(id), "green"), 255)
        call SetTextTagVisibility(TALKTAG[id], true)
        call SetTextTagFadepoint(TALKTAG[id], 4.5)
        call SetTextTagLifespan(TALKTAG[id], 5)
        call SetTextTagPermanent(TALKTAG[id], false)
    elseif GetItemTypeId(GetSoldItem()) == 'Mctg' then
        call RemoveItem(GetSoldItem())
        call AddItemToStock(c, 'Mctg', 1, 1)
        call SimError(Player(id), "You're already playing a minigame!")
        call SetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(id), PLAYER_STATE_RESOURCE_GOLD) + 1 )
    endif
 return false
endfunction

//===========================================================================
public function init takes nothing returns nothing
 set gg_trg_ColorGame = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ColorGame, EVENT_PLAYER_UNIT_SELL_ITEM )
    call TriggerAddCondition( gg_trg_ColorGame, function RemoveIt )
    set CG = InitHashtable()
endfunction

endscope
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
Better still, store them in some constant globals and just reference them (make sure you do initialize the string as an empty string ofcourse).

The split may be caused by how the game handles strings (they are objects that variables point to). Doing Bribe's solution or mine should mean the string is already loaded into the global string pool and thus exists for everyone (so you mearly change the link to it).
 
Status
Not open for further replies.
Top