16

» WarCraft 3 / возможно ли ч/з BJDebugMsg передать разный текст разным игрокам?

Принятый ответ
Нельзя.
вообще-то можно
вот код
function test takes nothing returns nothing
local integer i=0
loop
exitwhen i>bj_MAX_PLAYERS
if GetLocalPlayer()==Player(i) then
call BJDebugMsg(I2S(GetPlayerId(GetLocalPlayer())))
endif
set i=i+1
endloop
endfunction
16

» WarCraft 3 / как сделать 3 разных действия с одной периодичностью по таймеру?

у меня выше с таймерами алгоритмика хромала (если несколько раз отправить -g - то чаще тикало, таймеры накладывались)
у nazarpunk алгоритмика хорошая и рабочая
вот что получилось для 4х игроков на таймерах:
(из них у 1го игрока идёт общий подсчёт действий, у остальных без подсчёта)
globals
integer PLAYERS=12
integer array GO
integer array N
timer array Ti
endglobals

function OnPeriodic_4 takes nothing returns nothing
local integer i=4
set N[i]=N[i]+1
if N[i]==1 then
call BJDebugMsg("Action 1: "+GetPlayerName(Player(i-1)))
elseif N[i]==2 then
call BJDebugMsg("Action 2: "+GetPlayerName(Player(i-1)))
elseif N[i]==3 then
call BJDebugMsg("Action 3: "+GetPlayerName(Player(i-1)))
set N[i]=0
endif
endfunction
function OnPeriodic_3 takes nothing returns nothing
local integer i=3
set N[i]=N[i]+1
if N[i]==1 then
call BJDebugMsg("Action 1: "+GetPlayerName(Player(i-1)))
elseif N[i]==2 then
call BJDebugMsg("Action 2: "+GetPlayerName(Player(i-1)))
elseif N[i]==3 then
call BJDebugMsg("Action 3: "+GetPlayerName(Player(i-1)))
set N[i]=0
endif
endfunction
function OnPeriodic_2 takes nothing returns nothing
local integer i=2
set N[i]=N[i]+1
if N[i]==1 then
call BJDebugMsg("Action 1: "+GetPlayerName(Player(i-1)))
elseif N[i]==2 then
call BJDebugMsg("Action 2: "+GetPlayerName(Player(i-1)))
elseif N[i]==3 then
call BJDebugMsg("Action 3: "+GetPlayerName(Player(i-1)))
set N[i]=0
endif
endfunction
function OnPeriodic_1 takes nothing returns nothing
local integer i=1
set N[i]=N[i]+1
if ModuloInteger(N[i],3)==1 then
call BJDebugMsg(I2S(N[i])+" Action 1: "+GetPlayerName(Player(i-1)))
elseif ModuloInteger(N[i],3)==2 then
call BJDebugMsg(I2S(N[i])+" Action 2: "+GetPlayerName(Player(i-1)))
elseif ModuloInteger(N[i],3)==0 then
call BJDebugMsg(I2S(N[i])+" Action 3: "+GetPlayerName(Player(i-1)))
//set N[i]=0
endif
endfunction

function GOO takes nothing returns nothing
local integer i=GetPlayerId(GetTriggerPlayer())+1
if GO[i]==0 then
set GO[i]=1
set Ti[i]=CreateTimer()
else
set GO[i]=0
call PauseTimer(Ti[i])
call DestroyTimer(Ti[i])
call BJDebugMsg("STOP: "+GetPlayerName(Player(i-1)))
endif
set N[i]=0
if GO[i]==1 and i==1 then
call TimerStart(Ti[i], 1, true, function OnPeriodic_1)
elseif GO[i]==1 and i==2 then
call TimerStart(Ti[i], 1, true, function OnPeriodic_2)
elseif GO[i]==1 and i==3 then
call TimerStart(Ti[i], 1, true, function OnPeriodic_3)
elseif GO[i]==1 and i==4 then
call TimerStart(Ti[i], 1, true, function OnPeriodic_4)
endif
endfunction

function Start takes nothing returns nothing
local string s=StringCase(GetEventPlayerChatString(),false)
if s=="-g" then
call GOO()
endif
endfunction

function Start_init takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=1
loop
exitwhen i>PLAYERS
call TriggerRegisterPlayerChatEvent(t,Player(i-1),"-",false)
set i=i+1
endloop
call TriggerAddAction(t,function Start)
endfunction

call Start_init()
Смысл примерно таков для цыкла
в первом твоём коде:
ты загнал таймер сразу в Start_init
хотя эта функция вообще за чат отвечает, как и Start
т.е. до твоей правки они были универсальны, а после твоей правки стали бесполезно-громоздки, т.к. получился отдельный большой тригер-чата исключительно под таймер
+ если я правильно прочитал твой код в Start_init - то при старте карты у тебя включится таймер в бэк режиме, оттягивая на себя ресурсы просто так
+ у нас с панком команда из чата работает как вкл/выкл, как и было заявлено в первом посте. а у тебя получается она является стартующей. т.е. она только вкл
+ дебаг:
:39: Index missing for array variable TIME
:40: Index missing for array variable TIME
надо заменить
"timer array TIME" на "timer TIME=null" - для 1го кода
или оставить "timer array TIME" - для 2го кода
в обоих случаях дебаг строка выходит только в 1й тик таймера и потом перестаёт выводиться. что-то с алгоритмикой
второй код аналогично - только первая строка
попробую поискать где ошибка и как-то адаптировать чтобы заработало
вот
ты этой строкой выключаешь таймер после первого тика сразу внутри самого таймера

по поводу твоего второго варианта:
каждый 1 тик работает 12 раз (по количеству плееров)
т.е. если 1й игрок пишет -g то за 1 тик выдает 12 строк
видимо потому что в Start_init ты 12 раз запускаешь 12 таймеров т.е. 12 функций OnPeriodic за 1 тик
попробуй сам на карте
Загруженные файлы
16

» WarCraft 3 / Депротект (знаю заеженная тема)

Вор
не вор , а моддер
или ты про воровство скопированных битов? своровать можно только физический оригинал и обладатель оригинала ОБЕДНЕЕТ на то количество штук, сколько ты своровал. а скопированные биты ты никак не можешь своровать. т.к. после копирования - это лично твоя копия и принадлежит тебе
или ты думаешь движок сайта xgm тоже с нуля писан и не задействует никаких сторонних библиотек?
а товарищ майор когда свою коробку СОРМ-2 и СОРМ-3 подключает между провайдером и тобой - он кто? вор или блюститель порядка?
16

» WarCraft 3 / как сделать 3 разных действия с одной периодичностью по таймеру?

Можно один таймер для всех, а когда таймер истекает, то циклом проверять всех игроков и в зависимости переменной записаной на игрока выполнять действия
я уже так попробовал, выше вот в начале этого сообщения , там всё описано. есть идеи по коду? либо свой напилить, либо у меня ошибку найти?



а тем временем я сделал говнокод (который работает) с полностью раздельными таймерами на каждого игрока
т.е Spell_1 Spell_2 Spell_3 + OnPeriodic_1 OnPeriodic_2 OnPeriodic_3
перехожу к триггерам и TriggerRegisterTimerEvent
как доделаю на тригерах - в один пост запощу оба варианта своего решения
16

» WarCraft 3 / как сделать 3 разных действия с одной периодичностью по таймеру?

Мне кажется
пока код не рабочий алгоритмически - есть ли смысл его оптимизировать и причёсывать?
16

» WarCraft 3 / как сделать 3 разных действия с одной периодичностью по таймеру?

не получается одной функцией обрабатывать отдельные таймеры под каждого игрока
каждый новый игрок включивший таймер ускоряет тик у каждого включившего.
т.е. если 3 игрока запустят таймер - то у всех из них тик будет чаще в 3 раза
или это надо делать своей отдельной функцией под каждого игрока?
т.е Spell_1 Spell_2 Spell_3 + OnPeriodic_1 OnPeriodic_2 OnPeriodic_3
бред конечно, что нельзя в таймерную функцию передавать переменные. кто-то запустил функцию по таймеру, а кто? да хз кто, тикает и ладно
globals
integer PLAYERS=12
integer array N
timer array Ti
timer array TIME
integer array GO
endglobals

function OnPeriodic takes nothing returns nothing
local integer i=1
loop
exitwhen i>PLAYERS
if GO[i]==1 then
set Ti[i] = GetExpiredTimer()
call BJDebugMsg("timer  i "+I2S(i)+"__GO[i] "+I2S(GO[i])+"__N [i] "+I2S(N[i])+"__Name "+GetPlayerName(Player(i-1)))
set N[i]=N[i]+1
endif
if GO[i]==0 then
call PauseTimer(Ti[i])
call DestroyTimer(Ti[i])
endif
set i=i+1
endloop
set Ti[i] = null
endfunction

function Spell takes nothing returns nothing
local integer i=GetPlayerId(GetTriggerPlayer())+1
set TIME[i] = CreateTimer()
call BJDebugMsg("TIME "+I2S(i))
call TimerStart(TIME[i], 1, true, function OnPeriodic)
set TIME[i] = null
endfunction

function GOO takes nothing returns nothing
local integer i=GetPlayerId(GetTriggerPlayer())+1
if GO[i]==0 then
set GO[i]=1
call BJDebugMsg("GO 1")
call Spell()
else
set GO[i]=0
call BJDebugMsg("GO 0")
set N[i]=0
endif
endfunction

function Start takes nothing returns nothing
local string s=StringCase(GetEventPlayerChatString(),false)
if s=="-g" then
call GOO()
endif
endfunction

function Start_init takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=1
loop
exitwhen i>PLAYERS
call TriggerRegisterPlayerChatEvent(t,Player(i-1),"-",false)
set i=i+1
endloop
call TriggerAddAction(t,function Start)
endfunction


Вот пример через глобалку сделал.
подпилил строки, так вроде?
integer i = 0;
BJDebugMsg("action 1: " + I2S(GetPlayerId(p)));
BJDebugMsg("action 2: " + I2S(GetPlayerId(p)));
BJDebugMsg("action 3: " + I2S(GetPlayerId(p)));
zinc to jass:
globals
integer MyTimerLib__n=-1
timer MyTimerLib__ticker=CreateTimer()
string MyTimerLib__msg="-run"
boolean MyTimerLib__running=false
player MyTimerLib__p
endglobals

function MyTimerLib__anon__1 takes nothing returns nothing
set MyTimerLib__n=MyTimerLib__n+1
if(MyTimerLib__n==0)then
call BJDebugMsg("action 1: "+I2S(GetPlayerId(MyTimerLib__p)))
endif
if(MyTimerLib__n==1)then
call BJDebugMsg("action 2: "+I2S(GetPlayerId(MyTimerLib__p)))
endif
if(MyTimerLib__n==2)then
call BJDebugMsg("action 3: "+I2S(GetPlayerId(MyTimerLib__p)))
set MyTimerLib__n=-1
endif
endfunction

function MyTimerLib__anon__0 takes nothing returns nothing
set MyTimerLib__p=GetTriggerPlayer()
if(MyTimerLib__running)then
call PauseTimer(MyTimerLib__ticker)
set MyTimerLib__n=-1
set MyTimerLib__running=false
call BJDebugMsg("stop")
return
endif
set MyTimerLib__running=true
call TimerStart(MyTimerLib__ticker,.3,true,function MyTimerLib__anon__1)
endfunction

function MyTimerLib__onInit takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=0
set i=0
loop
exitwhen(i>=bj_MAX_PLAYER_SLOTS)
if(GetPlayerController(Player(i))==MAP_CONTROL_USER and GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING)then
call TriggerRegisterPlayerChatEvent(t,Player(i),MyTimerLib__msg,false)
endif
set i=i+1
endloop
call TriggerAddAction(t,function MyTimerLib__anon__0)
set t=null
endfunction

call ExecuteFunc("MyTimerLib__onInit")
твой код работает если таймер один общий на всех, только я уже дальше пошёл в самом верху этого сообщения, пытаясь запилить свои действия для каждого игрока, пока не выходит чаша
Загруженные файлы
16

» WarCraft 3 / как сделать 3 разных действия с одной периодичностью по таймеру?

! zinc
zinc to jass:
globals
integer MyTimerLib___n=-1
timer MyTimerLib___ticker=CreateTimer()
integer MyTimerLib___i=GetPlayerId(GetTriggerPlayer())
endglobals

function MyTimerLib___anon__0 takes nothing returns nothing
set MyTimerLib___n=MyTimerLib___n+1
if(MyTimerLib___n==0)then
call BJDebugMsg("111 "+I2S(MyTimerLib___i))
endif
if(MyTimerLib___n==1)then
call BJDebugMsg("222 "+I2S(MyTimerLib___i))
endif
if(MyTimerLib___n==2)then
call BJDebugMsg("333 "+I2S(MyTimerLib___i))
set MyTimerLib___n=-1
endif
endfunction

function MyTimerLib___onInit takes nothing returns nothing
call TimerStart(MyTimerLib___ticker,.3,true,function MyTimerLib___anon__0)
endfunction
call ExecuteFunc("MyTimerLib___onInit")



как передать GetPlayerId(GetTriggerPlayer()) в таймерную функцию MyTimerLib___anon__0 ?
или таймер такого не может - поэтому надо перебором всех плееров?
16

» WarCraft 3 / Как вставить карту в другую карту?

Я провёл эксперимент и вставил на свою карту фрагмент из другой, и другие вставали нормально
а на других картах была вода?
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

Да, по числу из чата.
с добрым утром, по числу из чата любой сможет
Зачем брать из камеры, если камера юзает число из чата?)
зачем брать из чата, когда можно взять из координат камеры?
ты сам пробовал хоть раз написать -создатьюнита +25724 -15876 ? попробуй
а потом попробуй 10 раз для разных координат написать
может потом ты поймешь смысол этой темы уже
если камера юзает число из чата?)
то был как пример синхронизации данных т.е вывода локального значения у локального игрока в глобальную общую переменную, но там же и указано, что такого невозможно сделать через чат, т.к. попросту на джасе нет функции написания сообщения в чат от игрока
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

GameCacheSync 2021

Warcraft III map script
Generated by the Warcraft III World Editor
Date: Sat Nov 27 19:10:21 2021
Map Author: Unryze & quq_CCCP
а статья от N1ghtSiren

бывают случаи что синх длится секунд 5
а это зависит от количества операций? одно дело периодически передавать координаты постоянно. а другое дело - передать две координаты, скажем 1 раз в 10 секунд или 1 раз в минуту. только вопрос - сколько строк кода такое займёт. я там вижу и доп файлы в той карте "ExtraCache.dat" "text.fdf" - слишком всё это громоздко, и наверное зависит от целеполагания. когда такая фича является основой карты - это можно понять. а когда хочешь сделать просто БОНУСОМ функцию, то пару сотен строк кода и доп файлы - дороговато
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

синхронизация не мгновенная, может понадобится несколько секунд
это не подходит. 0,2-0,5 секунды это максимально допустимый инпут лаг
quq_CCCP:
На сайте полно примеров работы с кешем, а так же статей по сихронизации
	if GetLocalPlayer()==GetOwningPlayer(s)then //взять конкретного игрока
	call StoreReal(AL,NKB(s),"MouseX",x) //засейвить мышь в хэш
	call StoreReal(AL,NKB(s),"MouseY",y)
	call SyncStoredReal(AL,NKB(s),"MouseX") //отправить кэш в синк
	call SyncStoredReal(AL,NKB(s),"MouseY")
	endif
	call StoreReal(AL,NKB(s),"MouseX",0) //перезаписать коорды всем
	call StoreReal(AL,NKB(s),"MouseY",0)
попробую покурить, посмотрю на инпут лаг
паладин перемещающийся по мыше красного игрока
о, там даже есть пример именно того что нужно
и инпут лаг как раз 0.2 сек
похоже на первое решение в этой теме, точно покурю
только видимо размер кода очень большой на всё это, измеряется сотнями строк
Среднее время синка - 0.16 секунд
о, глазомер в порядке
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

ты куда
пиши код
EugeAl:
сделать глобал массив чисел, куда отправлять все 2500 итп по индексу игрока, вводящего сообщение
пример кода? имеется ввиду ставить зум по числу из чата? или что?
команды из чата не десинхронят
но задача состоит в том, чтобы получить число 2500 не из чата (путём ввода игроком этих 2500), а напрямую из настроек камеры игрока либо если такое невозможно - то признаться что такое невозможно сделать
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

создать массивы точек
давай ещё раз
ты мне предлагаешь задать самому в коде переменные set X=100 set Y=200 и создать по этим координатам там же в коде юнита? так?
или как конкретно ты предлагаешь создать массив точек? пиши код

Просто возьми друга
на xgm ещё не изобрели multiwindow ?
Borodach:
))
протести создание юнита в центре камеры, с вероятностю в 98% десинхрона не будет
я это протестил ещё ДО создания этой темы
и если бы десинхрона от координат камеры не было, этой темы бы тоже не было
да даже без тестов ясно как белый день что будет десинхрон
и да, на тестах десинхрон был физический а не только в значениях переменных
и да, на разных клиентах был разный результат исполнения кода
и да, на одном клиенте был объект, а на втором клиенте не было объекта
но это не десинхрон, это просто надо "правильно" кодить. но как конкретно - за 20 коментов никто не знает , да?
)))))))))))))) пиу пиу тирлюм тирлюм )))))))) весила смишна ))))))
Borodach:
Но не проверяй значение переменных, а именно функцию в целом.
а если у вас десинхрон это не разные значения у одних и тех же переменных, а табличка "ОЖИДАНИЕ ИГРОКА" - то удачи. щас бы сидеть и ловить когда игра обнаружит несоответствие переменных и выдаст тебе табличку не сразу в моменте, а минуты через две. зато две минуты не было десинхрона ага
Borodach:
с вероятностю в 98% десинхрона не будет
это после таких советов появляются карты, которые крашат даже на стадии инициализации? а "умные" дяди советуют перезайти в лобби после скачки карты? а из новшеств в карте примерно НИЧЕГО особенного, но ты перезайди, а то вася-кодер криво накодил и обложил всё мемхаками. да?
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

Подрузамевается синхронизация значений между игроками.
т.е. я спрашиваю как по координатам камеры одного из игроков создать юнита, а мне в ответ предлагают поставить камеры всех игроков в одну (неизвестно какую) точку и там заспавнить юнита? а камеры потом пусть игроки возвращают самостоятельно в исходные точки? я сейчас правильно перевёл твою мысль?
nazarpunk:
Какая версия игры имеется ввиду?
1.26
Загруженные файлы
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

кто мешает синхронизировать координаты
что под этим понятием имеется ввиду?
nazarpunk:
любым методом по вкусу
какие несколько методов имеются ввиду?
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

когда будут конкретные вопросы а не влажные абстрактные фантазии тогда поговорим.
тебя бы следовало игнорировать, т.к. решений от тебя не будет
но смотри, публичная проверка:
как, зная координаты центра камеры игрока, или по-другому - координаты его центра экрана, то есть имея значения X Y - GetCameraTargetPositionX() GetCameraTargetPositionY() - заспавнить в этом центре по этим координатам, через строку чата, скажем, юнита, и не поймать десинхрона, чтобы этот юнит появился у всех игроков. т.е. перевести локальные координаты камеры игрока в глобального юнита.
ещё раз - игрок пишет тригер-текст в чат -unitcam и в его текущих координатах экрана GetCameraTargetPositionX() GetCameraTargetPositionY() (в момент нажатия клавиши Enter) появляется юнит без десинхрона и все другие игроки его видят
либо ты выдаёшь решение, ответом на этот пост
либо пишешь "ой, тебя неправильно поняли"
три, два, один:
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

это самый главный вопрос.
самый главный вопрос находится в шапке темы
Hate:
если вы не можете ответить на него, то оно вам не нужно. тогда следует вопрос, зачем вы пытаетесь решать несуществующие проблемы?
приём пациентов у домашних психотерапевтов - в соседней комнате, так что ты ошибся дверью со своими левыми вопросами не по теме и такими же левыми выводами - сам придумал, сам сделал выводы, сам парировал
за сим делаю вывод: такое средствами JASS сделать невозможно, раз за сутки никто не смог ответить на базовый вопрос
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

--где-то тут должна быть конструкция по обращению к нужному игроку
оба кода ниже выдают одинаковый результат -> разные значения zz для двух разных игроков:
(у одного 0 а у второго размер зума)
(тригерит только один игрок чатом)
т.е. не позволяют вывести локальное значение в глобалку
function GetLocalCameraField takes integer i returns integer
local integer j=0
if GetLocalPlayer()==Player(i-1) then
set j = R2I(GetCameraField(CAMERA_FIELD_TARGET_DISTANCE))
return j
endif
endfunction
local integer i=GetPlayerId(GetTriggerPlayer())+1
set zz = GetLocalCameraField(i)
call BJDebugMsg("zz = "+I2S(zz))
function GetLocalCameraField takes integer i returns integer
local integer j=0
if GetLocalPlayer()==Player(i-1) then
set j = R2I(GetCameraField(CAMERA_FIELD_TARGET_DISTANCE))
endif
return j
endfunction
local integer i=GetPlayerId(GetTriggerPlayer())+1
set zz = GetLocalCameraField(i)
call BJDebugMsg("zz = "+I2S(zz))
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

До того момента пока эта переменная не будет использоваться где-то в синх данных
так я её для того и загоняю в переменную, с целью использовать далее глобально с остальными общими данными
Hate:
зачем остальным игрокам необходимо знать зум остальных?
я так захотел
Hate:
еще раз спрашиваю
ещё вопросы? содержимое карманов показывать? 10 раз приседать?
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

так десинк то есть?
если одна глобальная переменная у разных игроков имеет разное значение - это десинх или нет?
Hate:
и зачем другим игрокам знать о зуме других игроков?
то был пример, когда значение переменной локального игрока никто не знает из остальных. будь то зум или иное локальное значение
а если его никто не знает, значит с ним нельзя толком работать
в данном примере - если зум одного игрока нельзя узнать остальным игрокам (а точнее загнать в глобальную переменную) никаким образом - достаточно просто написать "нельзя" в виде ответа
либо если можно - то как?
под "другими игроками" я имею ввиду всю карту в целом. если карта не может загнать значения в глобалки - значит смысла в таких глобалках нет
16

» WarCraft 3 / как присвоить локальные значения игрока в глобальные переменные?

это вы проверяли?
конечно, если запускать функцию через чат и i=GetPlayerId(GetTriggerPlayer())+1, то только у него лично и изменится глобальная переменная, а у остальных кто не писал в чат - у них останется старое значение
16

» WarCraft 3 / Депротект (знаю заеженная тема)

Так я вообще не в курсах о таких вещах как листфайл
уже целых 3 дня прошло с момента создания тобой темы, а ты до сих пор не в курсах?
ты об этом должен быть в курсах ещё ДО открытия j файла (или любого другого)
поэтому твой уровень знания jass тут не играет роли
ты даже ответы в этой теме читаешь через слово
Мне бы хотелось читабельности как и легкости редактирования
оу рили? а другим этого не хочется и охота копаться в ассемблере на перфокартах?
что war3restorer мне предоставил, а остальное это слишком муторно
неужели? муторно? мм
а ты не думал, что открыть карту это не в туалет сходить?
помогите кто в чем сможет
делать за тебя 2 недели работы? а какой тариф в рублях?