Раздел:
Основы

Циклы и их лимиты (JASS)

Автор статьи: host_pi
Вот у нас есть код:
function Loop0 takes nothing returns nothing
	local integer i = 0
	local integer TOTAL = 10000
	loop
		set i = i + 1
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i))
endfunction
и казалось бы, всё работает, что ещё надо?
Но добавив всего 1 строку BJDebugMsg в этот цикл - он остановится не на 10000, а на 800 и с обрывом перестанет исполняться
function Loop1 takes nothing returns nothing
	local integer i = 0
	local integer TOTAL = 10000
	loop
		set i = i + 1
		call BJDebugMsg(I2S(i))
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i))
endfunction
точно также остановятся и следующие 9 вариаций с циклами (только Loop8 сможет дотянуть аж до 2500 из 10000, а Loop9 дотянет до 30000 из 50000)
Loop2 - на глобалках - 800 / 2000
function Loop2 takes nothing returns nothing
	local integer bj_forLoopAIndexEnd = 2000
	set bj_forLoopAIndex = 0
	loop
		set bj_forLoopAIndex = bj_forLoopAIndex + 1
		call BJDebugMsg(I2S(bj_forLoopAIndex))
		exitwhen bj_forLoopAIndex == bj_forLoopAIndexEnd
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(bj_forLoopAIndex))
endfunction
Loop3 - два цикла подряд - 500+300 / 1000
function Loop3 takes nothing returns nothing
	local integer i = 0
	local integer k = 0
	local integer TOTAL = 500
	loop
		set k = k + 1
		set i = i + 1
		call BJDebugMsg(I2S(i)+"-"+I2S(k))
		exitwhen i == TOTAL
	endloop
	set i = 0
	loop
		set k = k + 1
		set i = i + 1
		call BJDebugMsg(I2S(i)+"-"+I2S(k))
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(k))
	call BJDebugMsg(I2S(i))
endfunction
Loop4 - вложенный цикл - 800 / 10000
function Loop4 takes nothing returns nothing
	local integer i1 = 0
	local integer i2 = 0
	local integer k = 0
	local integer TOTAL = 100
	loop
		set i1 = i1 + 1
		set i2 = 0
		loop
			set k = k + 1
			set i2 = i2 + 1
			call BJDebugMsg(I2S(i1)+"-"+I2S(i2)+"-"+I2S(k))
			exitwhen i2 == TOTAL
		endloop
		exitwhen i1 == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(k))
	call BJDebugMsg(I2S(i1))
	call BJDebugMsg(I2S(i2))
endfunction
Loop5 - вызов функции - 800 / 10000
function Loop5 takes nothing returns nothing
	call Loop1()
endfunction
Loop6 - другой вызов функции - 800 / 10000
function Loop6 takes nothing returns nothing
	call ExecuteFunc("Loop1")
endfunction
Loop7 - вызов нескольких малых функций 500+300 / 1000
function Loop7_2 takes integer i, integer j returns integer
	loop
		set i = i + 1
		call BJDebugMsg(I2S(j)+"-"+I2S(i))
		exitwhen i == 500
	endloop
	return i
endfunction

function Loop7 takes nothing returns nothing
	local integer i=0
	call BJDebugMsg("--1--")
	set i=i+Loop7_2(0,1)
	call BJDebugMsg("--2--")
	set i=i+Loop7_2(0,2)
	call BJDebugMsg("--E--")
	call BJDebugMsg(I2S(i))
endfunction
Loop8 - цикл с использованием ForForce - 2500 / 10000
function Loop8_2 takes nothing returns nothing
	loop
		set bj_forLoopAIndex = bj_forLoopAIndex + 1
		call BJDebugMsg(I2S(bj_forLoopAIndex))
		exitwhen bj_forLoopAIndex == bj_forLoopAIndexEnd
	endloop
	set bj_forLoopAIndex = bj_forLoopAIndex - 1
endfunction

function Loop8 takes nothing returns nothing
	set bj_forLoopAIndex=0
	set bj_forLoopAIndexEnd=10000
	call ForForce(bj_FORCE_PLAYER[0], function Loop8_2)
	call BJDebugMsg("--1--")
	call ForForce(bj_FORCE_PLAYER[0], function Loop8_2)
	call BJDebugMsg("--2--")
	call ForForce(bj_FORCE_PLAYER[0], function Loop8_2)
	call BJDebugMsg("--E--")
	call BJDebugMsg(I2S(bj_forLoopAIndex))
endfunction
Loop9 - через триггер 30000 / 50000
function Loop9_2 takes nothing returns nothing
	set bj_forLoopAIndex = bj_forLoopAIndex + 1
	call BJDebugMsg(I2S(bj_forLoopAIndex))
endfunction

function Loop9 takes nothing returns nothing
	local integer TOTAL = 50000
	local trigger t=null
	set t = CreateTrigger()
	call TriggerAddAction(t, function Loop9_2)
	set bj_forLoopAIndex=0
	loop
		call TriggerExecute(t)
		exitwhen bj_forLoopAIndex == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(bj_forLoopAIndex))
endfunction

Заметка:

а дальше интересный момент - если в Loop1 заменить BJDebugMsg на DisplayTimedTextToPlayer, то количество итераций сразу вырастет с 800 до 9700 (потому что 1 BJDebugMsg это 12 раз DisplayTimedTextToPlayer, даже если в карте 2 слота для игроков)
Loop10 - замена BJDebugMsg на DisplayTimedTextToPlayer - 9700 / 20000
function Loop10 takes nothing returns nothing
	local integer i = 0
	local integer TOTAL =20000
	loop
		set i = i + 1
		call DisplayTimedTextToPlayer(Player(0),0,0,1,I2S(i)) //LIMIT 9700
		//call BJDebugMsg(I2S(i)) //LIMIT 800
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i))
endfunction
function BJDebugMsg takes string msg returns nothing
//    constant integer   bj_MAX_PLAYERS                   =  12
    local integer i = 0
    loop
        call DisplayTimedTextToPlayer(Player(i),0,0,60,msg)
        set i = i + 1
        exitwhen i == bj_MAX_PLAYERS
    endloop
endfunction

Причина:

циклы обрываются, потому что все команды выполняются в одной очереди, в одном стеке. поэтому он переполняется и обрывается. для обхода этого переполнения нужно использовать Loop11 , Loop12 , Loop13
Loop11 - через TriggerEvaluate - 400000 / 400000
globals
	trigger loop11_2 = CreateTrigger()
	trigger loop11_3 = CreateTrigger()
	integer i1
	integer i2
	integer i3
	integer i123
	integer i123TOTAL=74
endglobals

function Loop11 takes integer TOTAL returns nothing
	set i123TOTAL=TOTAL
	set i123=0
	set i1 = 0
	loop
		set i1 = i1 + 1
		call TriggerEvaluate(loop11_2)
		exitwhen i1 == i123TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i123))
endfunction

function Loop11_2 takes nothing returns boolean
	set i2 = 0
	loop
		set i2 = i2 + 1
		call TriggerEvaluate(loop11_3)
		exitwhen i2 == i123TOTAL
	endloop
	return false
endfunction

function Loop11_3 takes nothing returns boolean
	set i3 = 0
	loop
		//Actions here
		set i3 = i3 + 1
		set i123=i123 + 1
		call BJDebugMsg(I2S(i1)+"-"+I2S(i2)+"-"+I2S(i3)) //CPU LIMIT
		exitwhen i3 == i123TOTAL
	endloop
	return false
endfunction

function Loop11_init takes nothing returns nothing
	call TriggerAddCondition(loop11_2, Condition(function Loop11_2))
	call TriggerAddCondition(loop11_3, Condition(function Loop11_3))
endfunction

function main takes nothing returns nothing
    call Loop11_init()
endfunction
Loop12 - через таймерный триггер - 400000 / 400000
globals
	integer array t_loop_N
	trigger array t_loop
	integer array t_loop_init
	hashtable ht = InitHashtable()
endglobals

function Loop12_Actions takes nothing returns nothing
	local integer i = LoadInteger(ht, GetHandleId(GetTriggeringTrigger()), 0)
	set t_loop_N[i] = t_loop_N[i] + 1
	call BJDebugMsg(I2S(t_loop_N[i]))
	if t_loop_N[i] == 400000 then
		call BJDebugMsg("-----")
		call BJDebugMsg(I2S(t_loop_N[i]))
		set t_loop_N[i] = 0
		call DisableTrigger(t_loop[i])
	endif
endfunction

function Loop12 takes nothing returns nothing
	local integer i = GetPlayerId(GetTriggerPlayer()) + 1
	if t_loop_init[i] == 0 then
		set t_loop_init[i] = 1
		set t_loop[i] = CreateTrigger()
		call SaveInteger(ht, GetHandleId(t_loop[i]), 0, i)
		call TriggerRegisterTimerEvent(t_loop[i], 0.001, true)
		call TriggerAddAction(t_loop[i], function Loop12_Actions)
		call DisableTrigger(t_loop[i])
	endif
	if IsTriggerEnabled(t_loop[i]) then
		call DisableTrigger(t_loop[i])
	else
		set t_loop_N[i]=0
		call EnableTrigger(t_loop[i])
	endif
endfunction
Loop13 - через таймер - 400000 / 400000
globals
	timer array ti_time
	integer array ti_N
	boolean array ti_run
	integer ti_i
endglobals

function Loop13_Actions takes nothing returns nothing
	set ti_i=LoadInteger(ht,GetHandleId(GetExpiredTimer()),0)
	set ti_N[ti_i]=ti_N[ti_i]+1
	call BJDebugMsg("Timer "+I2S(ti_i)+" - "+I2S(ti_N[ti_i]))
	if ti_N[ti_i]==400000 then
		call PauseTimer(ti_time[ti_i])
		set ti_N[ti_i]=0
		set ti_run[ti_i]=false
		call BJDebugMsg("Player: "+I2S(ti_i)+", Autostop")
	endif
endfunction

function Loop13_Time takes nothing returns nothing
	set ti_i=GetPlayerId(GetTriggerPlayer())
	if(ti_run[ti_i])then
		call PauseTimer(ti_time[ti_i])
		set ti_N[ti_i]=0
		set ti_run[ti_i]=false
		call BJDebugMsg("Player: "+I2S(ti_i)+", Stop")
		return
	endif
	set ti_run[ti_i]=true
	call TimerStart(ti_time[ti_i],0.005,true,function Loop13_Actions)
endfunction

function Loop13_init takes nothing returns nothing
	local trigger t=CreateTrigger()
	set ti_i=0
	loop
		exitwhen(ti_i>=bj_MAX_PLAYER_SLOTS)
		if(GetPlayerController(Player(ti_i))==MAP_CONTROL_USER and GetPlayerSlotState(Player(ti_i))==PLAYER_SLOT_STATE_PLAYING)then
			call TriggerRegisterPlayerChatEvent(t,Player(ti_i),"-l13",false)
			set ti_N[ti_i]=0
			set ti_run[ti_i]=false
			set ti_time[ti_i]=CreateTimer()
			call SaveInteger(ht,GetHandleId(ti_time[ti_i]),0,ti_i)
		endif
		set ti_i=ti_i+1
	endloop
	call TriggerAddAction(t,function Loop13_Time)
	set t=null
endfunction

function main takes nothing returns nothing
    call Loop13_init()
endfunction
все три цикла дошли до 400000:

Бонус:

ну и ниже бонусная функция Preload с замером выполнения каждого действия. создаёт файлы в папке Warcraft\save-test\*.txt
и в каждом файле пишет строку call PreloadEnd( 0.0 )
если добавить туда какую-нибудь функцию, то можно отследить скорость её выполнения
а также отследить замедление - например если в 1.txt будет написано PreloadEnd( 0.1 ) это 0.1 сек , а в 50.txt будет написано PreloadEnd( 3.2 ) - значит 3.2 сек, что к середине цикла аж в 30 раз медленнее
Loop14 - Debug через Preload
function Loop14_Debug takes integer i, string txt returns nothing
	call PreloadGenClear()
	call PreloadGenStart()
	//Long Actions Here
	call Preload(txt+I2S(i))
	call PreloadGenEnd("save-test\\"+I2S(i)+".txt")
endfunction

function Loop14 takes nothing returns nothing
	local integer i = 0
	local integer TOTAL = 100
	local string txt=""
	loop
		set txt = GetPlayerName(GetTriggerPlayer())
		set i = i + 1
		//Long Actions Here
		call Loop14_Debug(i,txt)
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i))
endfunction

Команды карты:

ниже прикреплена карта с примерами:
в чате вводить такие команды:
-l0 или -l / Loop0
-l1 / Loop1
-l2 / Loop2
-l3 / Loop3
-l4 / Loop4
-l5 / Loop5
-l6 / Loop6
-l7 / Loop7
-l8 / Loop8
-l9 / Loop9
-l10 / Loop10
-l11 / Loop11 20
-l11 XX / Loop11 XX - ввод кубический. т.е. ввод -l11 10 даст 10x10x10=1000 итераций, -l11 20 даст 8000, l11 50 даст 125000
-l12 / Loop12
-l13 / Loop13
-l14 / Loop14

Производительность:

Loop11 - TriggerEvaluate - зависнет пока не доделает
Loop12 - таймерный триггер TriggerRegisterTimerEvent - неплохо работает на скорости 0.001, к 350000 начинает чуть подтормаживать - на 400000 итераций уходит 7 минут
Loop13 - таймер TimerStart - на скорости 0.001 нокаутирует варик на 120 000, нормально работает на 0.004 / 0.005 - т.е. таймер раза в 4 прожорливее чем таймерный триггер
А также - если держать окно варика активным а не переключаться в другое окно - то варик будет работать чуть стабильнее
Итог - Loop12 является самым оптимальным и быстрым. Лучше чем Loop11 тем, что можно настраивать временной интервал и лучше чем Loop13 тем, что потребляет меньше ресурсов

Код карты:

Открыть спойлер с кодом карты

//***************************************************************************
//*
//*  Global Variables
//*
//***************************************************************************

globals
	trigger loop11_2 = CreateTrigger()
	trigger loop11_3 = CreateTrigger()
	integer i1
	integer i2
	integer i3
	integer i123
	integer i123TOTAL=74

	integer array t_loop_N
	trigger array t_loop
	integer array t_loop_init
	hashtable ht = InitHashtable()

	timer array ti_time
	integer array ti_N
	boolean array ti_run
	integer ti_i
endglobals

function Loop0 takes nothing returns nothing
	local integer i = 0
	local integer TOTAL = 10000
	loop
		set i = i + 1
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i))
endfunction

function Loop1 takes nothing returns nothing
	local integer i = 0
	local integer TOTAL = 2000
	loop
		set i = i + 1
		call BJDebugMsg(I2S(i))
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i))
endfunction

function Loop2 takes nothing returns nothing
	local integer bj_forLoopAIndexEnd = 2000
	set bj_forLoopAIndex = 0
	loop
		set bj_forLoopAIndex = bj_forLoopAIndex + 1
		call BJDebugMsg(I2S(bj_forLoopAIndex))
		exitwhen bj_forLoopAIndex == bj_forLoopAIndexEnd
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(bj_forLoopAIndex))
endfunction

function Loop3 takes nothing returns nothing
	local integer i = 0
	local integer k = 0
	local integer TOTAL = 500
	loop
		set k = k + 1
		set i = i + 1
		call BJDebugMsg(I2S(i)+"-"+I2S(k))
		exitwhen i == TOTAL
	endloop
	set i = 0
	loop
		set k = k + 1
		set i = i + 1
		call BJDebugMsg(I2S(i)+"-"+I2S(k))
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(k))
	call BJDebugMsg(I2S(i))
endfunction

function Loop4 takes nothing returns nothing
	local integer i1 = 0
	local integer i2 = 0
	local integer k = 0
	local integer TOTAL = 100
	loop
		set i1 = i1 + 1
		set i2 = 0
		loop
			set k = k + 1
			set i2 = i2 + 1
			call BJDebugMsg(I2S(i1)+"-"+I2S(i2)+"-"+I2S(k))
			exitwhen i2 == TOTAL
		endloop
		exitwhen i1 == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(k))
	call BJDebugMsg(I2S(i1))
	call BJDebugMsg(I2S(i2))
endfunction

function Loop5 takes nothing returns nothing
	call Loop1()
endfunction

function Loop6 takes nothing returns nothing
	call ExecuteFunc("Loop1")
endfunction

function Loop7_2 takes integer i, integer j returns integer
	loop
		set i = i + 1
		call BJDebugMsg(I2S(j)+"-"+I2S(i))
		exitwhen i == 500
	endloop
	return i
endfunction

function Loop7 takes nothing returns nothing
	local integer i=0
	call BJDebugMsg("--1--")
	set i=i+Loop7_2(0,1)
	call BJDebugMsg("--2--")
	set i=i+Loop7_2(0,2)
	call BJDebugMsg("--E--")
	call BJDebugMsg(I2S(i))
endfunction

function Loop8_2 takes nothing returns nothing
	loop
		set bj_forLoopAIndex = bj_forLoopAIndex + 1
		call BJDebugMsg(I2S(bj_forLoopAIndex))
		exitwhen bj_forLoopAIndex == bj_forLoopAIndexEnd
	endloop
	set bj_forLoopAIndex = bj_forLoopAIndex - 1
endfunction

function Loop8 takes nothing returns nothing
	set bj_forLoopAIndex=0
	set bj_forLoopAIndexEnd=10000
	call ForForce(bj_FORCE_PLAYER[0], function Loop8_2)
	call BJDebugMsg("--1--")
	call ForForce(bj_FORCE_PLAYER[0], function Loop8_2)
	call BJDebugMsg("--2--")
	call ForForce(bj_FORCE_PLAYER[0], function Loop8_2)
	call BJDebugMsg("--E--")
	call BJDebugMsg(I2S(bj_forLoopAIndex))
endfunction

function Loop9_2 takes nothing returns nothing
	set bj_forLoopAIndex = bj_forLoopAIndex + 1
	call BJDebugMsg(I2S(bj_forLoopAIndex))
endfunction

function Loop9 takes nothing returns nothing
	local integer TOTAL = 50000
	local trigger t=null
	set t = CreateTrigger()
	call TriggerAddAction(t, function Loop9_2)
	set bj_forLoopAIndex=0
	loop
		call TriggerExecute(t)
		exitwhen bj_forLoopAIndex == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(bj_forLoopAIndex))
endfunction

function Loop10 takes nothing returns nothing
	local integer i = 0
	local integer TOTAL =20000
	loop
		set i = i + 1
		call DisplayTimedTextToPlayer(Player(0),0,0,1,I2S(i)) //LIMIT 9700
		//call BJDebugMsg(I2S(i)) //LIMIT 800
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i))
endfunction

function Loop11 takes integer TOTAL returns nothing
	set i123TOTAL=TOTAL
	set i123=0
	set i1 = 0
	loop
		set i1 = i1 + 1
		call TriggerEvaluate(loop11_2)
		exitwhen i1 == i123TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i123))
endfunction

function Loop11_2 takes nothing returns boolean
	set i2 = 0
	loop
		set i2 = i2 + 1
		call TriggerEvaluate(loop11_3)
		exitwhen i2 == i123TOTAL
	endloop
	return false
endfunction

function Loop11_3 takes nothing returns boolean
	set i3 = 0
	loop
		//Actions here
		set i3 = i3 + 1
		set i123=i123 + 1
		call BJDebugMsg(I2S(i1)+"-"+I2S(i2)+"-"+I2S(i3)) //CPU LIMIT
		exitwhen i3 == i123TOTAL
	endloop
	return false
endfunction

function Loop11_init takes nothing returns nothing
	call TriggerAddCondition(loop11_2, Condition(function Loop11_2))
	call TriggerAddCondition(loop11_3, Condition(function Loop11_3))
endfunction

function Loop12_Actions takes nothing returns nothing
	local integer i = LoadInteger(ht, GetHandleId(GetTriggeringTrigger()), 0)
	set t_loop_N[i] = t_loop_N[i] + 1
	call BJDebugMsg(I2S(t_loop_N[i]))
	if t_loop_N[i] == 400000 then
		call BJDebugMsg("-----")
		call BJDebugMsg(I2S(t_loop_N[i]))
		set t_loop_N[i] = 0
		call DisableTrigger(t_loop[i])
	endif
endfunction

function Loop12 takes nothing returns nothing
	local integer i = GetPlayerId(GetTriggerPlayer()) + 1
	if t_loop_init[i] == 0 then
		set t_loop_init[i] = 1
		set t_loop[i] = CreateTrigger()
		call SaveInteger(ht, GetHandleId(t_loop[i]), 0, i)
		call TriggerRegisterTimerEvent(t_loop[i], 0.001, true)
		call TriggerAddAction(t_loop[i], function Loop12_Actions)
		call DisableTrigger(t_loop[i])
	endif
	if IsTriggerEnabled(t_loop[i]) then
		call DisableTrigger(t_loop[i])
	else
		set t_loop_N[i]=0
		call EnableTrigger(t_loop[i])
	endif
endfunction

function Loop13_Actions takes nothing returns nothing
	set ti_i=LoadInteger(ht,GetHandleId(GetExpiredTimer()),0)
	set ti_N[ti_i]=ti_N[ti_i]+1
	call BJDebugMsg("Timer "+I2S(ti_i)+" - "+I2S(ti_N[ti_i]))
	if ti_N[ti_i]==400000 then
		call PauseTimer(ti_time[ti_i])
		set ti_N[ti_i]=0
		set ti_run[ti_i]=false
		call BJDebugMsg("Player: "+I2S(ti_i)+", Autostop")
	endif
endfunction

function Loop13_Time takes nothing returns nothing
	set ti_i=GetPlayerId(GetTriggerPlayer())
	if(ti_run[ti_i])then
		call PauseTimer(ti_time[ti_i])
		set ti_N[ti_i]=0
		set ti_run[ti_i]=false
		call BJDebugMsg("Player: "+I2S(ti_i)+", Stop")
		return
	endif
	set ti_run[ti_i]=true
	call TimerStart(ti_time[ti_i],0.005,true,function Loop13_Actions)
endfunction

function Loop13_init takes nothing returns nothing
	local trigger t=CreateTrigger()
	set ti_i=0
	loop
		exitwhen(ti_i>=bj_MAX_PLAYER_SLOTS)
		if(GetPlayerController(Player(ti_i))==MAP_CONTROL_USER and GetPlayerSlotState(Player(ti_i))==PLAYER_SLOT_STATE_PLAYING)then
			call TriggerRegisterPlayerChatEvent(t,Player(ti_i),"-l13",false)
			set ti_N[ti_i]=0
			set ti_run[ti_i]=false
			set ti_time[ti_i]=CreateTimer()
			call SaveInteger(ht,GetHandleId(ti_time[ti_i]),0,ti_i)
		endif
		set ti_i=ti_i+1
	endloop
	call TriggerAddAction(t,function Loop13_Time)
	set t=null
endfunction

function Loop14_Debug takes integer i, string txt returns nothing
	call PreloadGenClear()
	call PreloadGenStart()
	//Long Actions Here
	call Preload(txt+I2S(i))
	call PreloadGenEnd("save-test\\"+I2S(i)+".txt")
endfunction

function Loop14 takes nothing returns nothing
	local integer i = 0
	local integer TOTAL = 100
	local string txt=""
	loop
		set txt = GetPlayerName(GetTriggerPlayer())
		set i = i + 1
		//Long Actions Here
		call Loop14_Debug(i,txt)
		exitwhen i == TOTAL
	endloop
	call BJDebugMsg("----")
	call BJDebugMsg(I2S(i))
endfunction

function Start takes nothing returns nothing
	local string s=GetEventPlayerChatString()
	if s=="-l0" or s=="-l" then
		call Loop0()
	elseif s=="-l1" then
		call Loop1()
	elseif s=="-l2" then
		call Loop2()
	elseif s=="-l3" then
		call Loop3()
	elseif s=="-l4" then
		call Loop4()
	elseif s=="-l5" then
		call Loop5()
	elseif s=="-l6" then
		call Loop6()
	elseif s=="-l7" then
		call Loop7()
	elseif s=="-l8" then
		call Loop8()
	elseif s=="-l9" then
		call Loop9()
	elseif s=="-l10" then
		call Loop10()
	elseif SubString(s,0,5)=="-l11 " then
		call Loop11(S2I(SubString(s,5,99)))
	elseif s=="-l11" then
		call Loop11(20)
	elseif s=="-l12" then
		call Loop12()
	elseif s=="-l14" then
		call Loop14()
	endif
endfunction

function Start_init takes nothing returns nothing
	local trigger t=CreateTrigger()
	local integer PLAYERS=12
	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

function InitGlobals takes nothing returns nothing
endfunction

//***************************************************************************
//*
//*  Unit Creation
//*
//***************************************************************************

//===========================================================================
function CreateUnitsForPlayer0 takes nothing returns nothing
    local player p = Player(0)
    local unit u
    local integer unitID
    local trigger t
    local real life

    set u = CreateUnit( p, 'Hblm', -143.7, -155.1, 106.197 )
endfunction

//===========================================================================
function CreatePlayerBuildings takes nothing returns nothing
endfunction

//===========================================================================
function CreatePlayerUnits takes nothing returns nothing
    call CreateUnitsForPlayer0(  )
endfunction

//===========================================================================
function CreateAllUnits takes nothing returns nothing
    call CreatePlayerBuildings(  )
    call CreatePlayerUnits(  )
endfunction

//***************************************************************************
//*
//*  Players
//*
//***************************************************************************

function InitCustomPlayerSlots takes nothing returns nothing

    // Player 0
    call SetPlayerStartLocation( Player(0), 0 )
    call ForcePlayerStartLocation( Player(0), 0 )
    call SetPlayerColor( Player(0), ConvertPlayerColor(0) )
    call SetPlayerRacePreference( Player(0), RACE_PREF_HUMAN )
    call SetPlayerRaceSelectable( Player(0), false )
    call SetPlayerController( Player(0), MAP_CONTROL_USER )

    // Player 1
    call SetPlayerStartLocation( Player(1), 1 )
    call ForcePlayerStartLocation( Player(1), 1 )
    call SetPlayerColor( Player(1), ConvertPlayerColor(1) )
    call SetPlayerRacePreference( Player(1), RACE_PREF_ORC )
    call SetPlayerRaceSelectable( Player(1), false )
    call SetPlayerController( Player(1), MAP_CONTROL_COMPUTER )

endfunction

function InitCustomTeams takes nothing returns nothing
    // Force: TRIGSTR_007
    call SetPlayerTeam( Player(0), 0 )

    // Force: TRIGSTR_008
    call SetPlayerTeam( Player(1), 1 )

endfunction

//***************************************************************************
//*
//*  Main Initialization
//*
//***************************************************************************

//===========================================================================
function main takes nothing returns nothing
    call Start_init()
    call Loop11_init()
    call Loop13_init()

    call SetCameraBounds( -3328.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), -3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 3328.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), -3328.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 3328.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), -3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM) )
    call SetDayNightModels( "Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdl", "Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdl" )
    call NewSoundEnvironment( "Default" )
    call SetAmbientDaySound( "LordaeronSummerDay" )
    call SetAmbientNightSound( "LordaeronSummerNight" )
    call SetMapMusic( "Music", true, 0 )
    call CreateAllUnits(  )
    call InitBlizzard(  )
    call InitGlobals(  )

endfunction

//***************************************************************************
//*
//*  Map Configuration
//*
//***************************************************************************

function config takes nothing returns nothing
    call SetMapName( "TRIGSTR_001" )
    call SetMapDescription( "TRIGSTR_003" )
    call SetPlayers( 2 )
    call SetTeams( 2 )
    call SetGamePlacement( MAP_PLACEMENT_USE_MAP_SETTINGS )

    call DefineStartLocation( 0, -128.0, -192.0 )
    call DefineStartLocation( 1, -128.0, -192.0 )

    // Player setup
    call InitCustomPlayerSlots(  )
    call InitCustomTeams(  )
endfunction

`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
1
32
5 месяцев назад
1
host_pi, нет, не припомню ни одной задачи, где бы были такие циклы.
2
20
5 месяцев назад
2
В картах обычно цикл до 8192 (прелести структур и вджасс) - и это подавляющее большинство. Если каким-то чудом цикл уже больше 8192 - то это скорее проблема разработчика, нежели ОП лимита.
И нет, обычно проблема не в циклах, а в перегруженности потока, который можно "разгружать" - да. Но все эти проблемы ОП лимита обходятся дроблениями main функции, да и самих циклов на отдельные "потоки" либо через ExecuteFunc, либо через TimerStart. В любом случае, такой прямо катастрофической проблемы банально нет.
Говоря проще, причина по которой не было подобных тем - скорее потому что ОП лимит достигается лишь фокусниками/извращенцами, нежели из-за неизбежности/случайно, ну а те, кто юзают Мемхак этот лимит могут поднять вручную, на UjAPI он вообще 2 миллиарда, а на рефе 30 миллионов с 300к.
Тут уже скорее проблема ванилы, но и она на деле не проблема, ибо испытывается единицами.
0
14
5 месяцев назад
Отредактирован host_pi
0
quq_CCCP: ни одной задачи, где бы были такие циклы
а я вот встретился с оплимитом в первой же карте, с которой работал - поэтому вообще без понятия - как за 20 лет вара челик 14го левела на хигаме - его ни разу не видел
и без подобных методов обхода оплимита - карта бы не работала как должна
классическое нинужна?
0
32
4 месяца назад
0
host_pi, потому что вы что то не то делайте, сами себе создаёте проблему.
0
14
4 месяца назад
Отредактирован host_pi
0
quq_CCCP: потому что вы что то не то делайте, сами себе создаёте проблему
ах да, это я такой криворукий, а не оплимит в варике
только вот сегодня утром опять наткнулся, уже в 3й раз в карте, на проблему оплимита в цикле, когда цикл тупо не доходит до конца и молча прерывается посередине
первый раз было с координатами юнитов - ладно, создал триггер вместо цикла - проблема решилась
вчера он аналогично не захотел обработать 50 строк длиннее 1000 символов - ну ладно, на тебе второй триггер
но нет же, сегодня во втором триггере заглох при обработке одной строки на 1400 символов (во время вызова доп функции) - пришлось делать триггер в триггере
итого 3 раза цикл из-за оплимита оборвался и не доработал, пока его на триггер не посадили
сидишь только и борешься с оплимитом в циклах сутками (а по пути на втором языке с нормальным отладчиком всё дублируешь),
действительно, никогда не было и вот опять
вместо работы над самой картой - для банальных вещей писать костыли к жасу, подпинывая эту калеку, чтобы он хоть как-то ходил
0
20
4 месяца назад
0
Скинь все эти карты, я готов тебе потыкать где и как создатель этих карт буквально нагадил и в коде и в штаны. А то этот сыр бор - банально мимо кассы.
И повторюсь, коли так тебя душат ОП лимиты у тебя есть несколько выборов:
  1. UjAPI.
  2. MemHack.
  3. Патч 1.29 или выше.
  4. Реф.
Тебя кто-то душит сидеть на 1.26а и тем более Ванильном? Если да, то тогда соизволь пытаться умещаться в лимиты, а не городить костыли обходить то, что достигаться и не должно.
1
18
4 месяца назад
Отредактирован Vlod
1
вчера он аналогично не захотел обработать 50 строк длиннее 1000 символов - ну ладно, на тебе второй триггер
но нет же, сегодня во втором триггере заглох при обработке одной строки на 1400 символов (во время вызова доп функции) - пришлось делать триггер в триггере
итого 3 раза цикл из-за оплимита оборвался и не доработал, пока его на триггер не посадили
сидишь только и борешься с оплимитом в циклах сутками
Да понимаю что это сложно, поэтому рекомендуй уйти на lua где нет такого лимита и больше перфоманс. Если такой возможности нет то дели код на части и делай отложенные вычисления типа таймером на 0 сек и т.п.
0
14
4 месяца назад
Отредактирован host_pi
0
Vlod: на lua нет такого лимита
каким же образом?
это религия альтернативно-кодеров?
каким образом можно писать что lua hrua cjass vjass ...{вставить ещё сотню языков} могут больше чем оригинал?
если они в конце компиляции тупо конвертят свой личный код в обычный жас
фактически это не больше чем обёртка от конфеты, только конфета остаётся всё той же
1
18
4 месяца назад
1
каким образом можно писать что lua hrua cjass vjass ...{вставить ещё сотню языков} могут больше чем оригинал?
если они в конце компиляции тупо конвертят свой личный код в обычный жас
lua не конвертируется в jass, это отдельный язык со своей luaVM который интегрируется в игру и дергает нативки как сишные функции, оп-лимит это прикол исключительно jassVM
1
14
4 месяца назад
Отредактирован host_pi
1
Vlod: lua не конвертируется в jass, это отдельный язык со своей luaVM который интегрируется в игру
а дай карту для 1.26, которая написана на луа и без жаса через супа пупа крутые dll интегрируется в игру
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.