Всем привет. Я хочу сделать локальный эффект сетки строительства для каждого игрока, чтобы кто ввел команду -grid, только для него и отображалась сетка. Суть в том что мой код работает в сингл плеере, но вызывает дисинх в мультиплеере. Я относительно новичок в jass и возможно где-то неправильно понял статью GetLocalPlayer. Ниже написан полный кусок кода, надеюсь на вашу помощь.
UPD: Речь идет о версии варкрафта 1.26, без мемхаков и ujapi
globals
    effect array gridFx
    boolean array gridOn
endglobals

function Grid_Create takes player p returns nothing
    local integer id = GetPlayerId(p)
    local integer i
    local integer j
    local integer startindex
    local integer index
    local integer step
    local integer side
    local real startX1 = -5888
    local real startY1 = 704
    local real startX2 = -3328
    local real startY2 = 768

    if GetLocalPlayer() == p then
    	if id <= 3 then
    		set side = 1
    	else
    		set side = -1
    	endif

    	set i = 0
    	set j = 0
    	set step = 15
    	set startindex = 0
    	loop
    		exitwhen i > 2
    		// i = Y ; j = X
    		set j = 0
    		loop
    			exitwhen j > 4
    				set index = startindex + j + i * 5 
    				set gridFx[index] = AddSpecialEffect("Grid(NoYellow).mdx", side * startX1 + 512 * j * side, startY1 + 512 * i)
    				set gridFx[index + step] = AddSpecialEffect("Grid(NoYellow).mdx", side * startX1 + 512 * j * side, (-1) * startY1 - 512 * i)
    				set j = j + 1
    		endloop
    		set i = i + 1
    	endloop

    	set i = 0
    	set j = 0
    	set step = 9
    	set startindex = 30
    	loop
    		exitwhen i > 2
    		// i = Y ; j = X
    		set j = 0
    		loop
    			exitwhen j > 2
    				set index = startindex + j + i * 3 
    				set gridFx[index] = AddSpecialEffect("Grid(NoYellow).mdx", side * startX2 + 512 * j * side, startY2 + 512 * i)
    				set gridFx[index + step] = AddSpecialEffect("Grid(NoYellow).mdx", side * startX2 + 512 * j * side, (-1) * startY2 - 512 * i)
    				set j = j + 1
    		endloop
    		set i = i + 1
    	endloop

        set gridOn[id] = true
    endif
endfunction


function Grid_Destroy takes player p returns nothing
    local integer id = GetPlayerId(p)
    local integer i = 0

    if GetLocalPlayer() == p then
        loop
            exitwhen i >= 48
            if gridFx[i] != null then
                call DestroyEffect(gridFx[i])
                set gridFx[i] = null
            endif
            set i = i + 1
        endloop

        set gridOn[id] = false
    endif
endfunction


function Grid_Toggle takes player p returns nothing
    local integer id = GetPlayerId(p)

    if gridOn[id] then
        //call DisplayTextToForce( GetLocalPlayer(), "Grid disable" )
        call Grid_Destroy(p)
    else
        //call DisplayTextToForce( GetLocalPlayer(), "Grid enable" )
        call Grid_Create(p)
    endif
endfunction

function Grid_Chat takes nothing returns nothing
    if SubString(GetEventPlayerChatString(), 0, 5) == "-grid" then
        call Grid_Toggle(GetTriggerPlayer())
    endif
endfunction

function InitTrig_grid takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    local integer i = 0

    loop
        exitwhen i > 5
        call TriggerRegisterPlayerChatEvent(t, Player(i), "", false)
        set i = i + 1
    endloop
    
    call TriggerAddAction(t, function Grid_Chat)
endfunction

Ты создаешь локально хэндл (AddSpecialEffect), отсюда десинх.
Строку названия эффекта локально меняй, а эффект создавай для всех.
`
ОЖИДАНИЕ РЕКЛАМЫ...
18
Принятый ответ
Ты создаешь локально хэндл (AddSpecialEffect), отсюда десинх.
Строку названия эффекта локально меняй, а эффект создавай для всех.
15
вот пример сетки на юнитах: (привязка сетки к юниту, сетка и есть юнит)
делаешь mdx, куда льёшь 2D прозрачную сетку, ставишь юнит-сетку куда надо по координатам
если у тебя 5 игроков, то делаешь 5 юнитов. и для каждого игрока 4 из них скрываешь а 1 оставляешь таким кодом:
call SetUnitVertexColorBJ(BackGroundUnits[i],0,0,0,100)
if Player(i-1)==GetLocalPlayer()then
call SetUnitVertexColorBJ(BackGroundUnits[i],100,100,100,0)
endif
вот пример сетки на фильтре (привязка сетки идёт на весь экран игрока): но на масштаб этого фильтра вроде влияет локальный зум камеры у игрока, лучше потестить лишний раз для каждого конкретного случая
вкл:
if GetLocalPlayer()==Player(i-1) then
call CinematicFilterGenericBJ(0,BLEND_MODE_BLEND,"war3mapImported\\xxx.blp",0,0,0,100,100,100,100,50)
endif
выкл:
if GetLocalPlayer()==Player(i-1) then
call CinematicFilterGenericBJ(0,BLEND_MODE_BLEND,"ReplaceableTextures\\CameraMasks\\White_mask.blp",0,0,0,100,100,100,100,100)
endif
оба способа не десинхают
если ты хочешь привязать к мышке игрока или к координатам его камеры/обзора - то тебе придется мучиться с мемхаком и прочими функциями синхронизации данных между игроками, которые занимают по 2000 строк
либо юзать сторонние WE, но и для запуска твоей карты потребуется тоже сторонний ланчер варика
по рефорджу не знаю, может там подвезли нативку синхронизации данных
хотя судя по коду у тебя вообще координаты сетки захардкожены соответственно синхронизация данных не требуется
1
Дико извиняюсь, что не упомянул сразу, сейчас отредачу вопрос. Речь конечно же идет о нашей любимой версии 1.26, в идеале без мем хаков и ужопы(пока что).
15
в идеале
в каком ещё идеале?
тебе уже 3 способа дали с конкретными решениями
почему ты их не протестил перед написанием поста? смысл писать ответы на твои вопросы тогда?
1
host_pi, еще не успел добраться до тестов, просто решил как можно быстрей ответить так как неверно вопрос задал. Буду как раз пытаться сейчас разбираться с этим, спасибо огромное за ответы
26
ты полностью не понял статью по локал плееру, марш перечитывать
1
OVOgenez, host_pi, Hate
Спасибо огромное за ответы. Перечитал статью GetLocalPlayer() несколько раз и до меня наконец дошло хоть какое-то понимание. Ниже отправлю какой код у меня получился в итоге. Решил все же использовать эффекты, через юнитов думаю реализовать подсказки для строительства(места где лучше строить). Насчет CinematicFilterGenericBJ я с ним не сталкивался и вообще не нашел примера как это выглядит, это прям отображение просто на экран?
globals
    effect array gridFx
    boolean array gridOn
endglobals

function Grid_Create takes player p returns nothing
    local integer id = GetPlayerId(p)
    local integer i
    local integer j
    local integer startindex
    local integer index
    local integer step
    local integer side
    local real startX1 = -5888
    local real startY1 = 704
    local real startX2 = -3328
    local real startY2 = 768
    local string e = ""

    if id <= 3 then
        set side = 1
    else
        set side = -1
    endif
    
	if (GetLocalPlayer() == p) then
		set e = "Grid(NoYellow).mdx"
	endif


    set i = 0
    set j = 0
    set step = 15
    set startindex = 0
    loop
        exitwhen i > 2
        // i = Y ; j = X
        set j = 0
        loop
            exitwhen j > 4
                set index = startindex + j + i * 5 + id * 48
                set gridFx[index] = AddSpecialEffect(e, side * startX1 + 512 * j * side, startY1 + 512 * i)
                set gridFx[index + step] = AddSpecialEffect(e, side * startX1 + 512 * j * side, (-1) * startY1 - 512 * i)
                set j = j + 1
        endloop
        set i = i + 1
    endloop

    set i = 0
    set j = 0
    set step = 9
    set startindex = 30
    loop
        exitwhen i > 2
        // i = Y ; j = X
        set j = 0
        loop
            exitwhen j > 2
                set index = startindex + j + i * 3 + id * 48
                set gridFx[index] = AddSpecialEffect(e, side * startX2 + 512 * j * side, startY2 + 512 * i)
                set gridFx[index + step] = AddSpecialEffect(e, side * startX2 + 512 * j * side, (-1) * startY2 - 512 * i)
                set j = j + 1
        endloop
        set i = i + 1
    endloop

    set gridOn[id] = true
    
endfunction


function Grid_Destroy takes player p returns nothing
    local integer id = GetPlayerId(p)
    local integer i = 0

    loop
        exitwhen i >= 48
        if gridFx[i + id * 48] != null then
            call DestroyEffect(gridFx[i + id * 48])
            set gridFx[i + id * 48] = null
        endif
        set i = i + 1
    endloop

    set gridOn[id] = false
endfunction


function Grid_Toggle takes player p returns nothing
    local integer id = GetPlayerId(p)

    if gridOn[id] then
        call DisplayTextToForce( bj_FORCE_PLAYER[id], "Grid disable" )
        call Grid_Destroy(p)
    else
        call DisplayTextToForce( bj_FORCE_PLAYER[id], "Grid enable" )
        call Grid_Create(p)
    endif
endfunction

function Grid_Chat takes nothing returns nothing
    if SubString(GetEventPlayerChatString(), 0, 5) == "-grid" then
        call Grid_Toggle(GetTriggerPlayer())
    endif
endfunction

function InitTrig_grid takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    local integer i = 0

    loop
        exitwhen i > 2
        call TriggerRegisterPlayerChatEvent(t, Player(i), "", false)
        call TriggerRegisterPlayerChatEvent(t, Player(i+6), "", false)
        set i = i + 1
    endloop
    
    call TriggerAddAction(t, function Grid_Chat)
endfunction
15
а почему мой ответ выделен принятым? твоё конечное решение на основе ответа от OVOgenez, его принятым и делай
26
niteko, пустую строку тоже нельзя оставлять, нужно явно указывать ".mdx"
1
Hate,
Отредактировал у себя в скрипте, спасибо
host_pi,
Я в итоге использовать буду оба метода
Чтобы оставить комментарий, пожалуйста, войдите на сайт.