14

» WarCraft 3 / Как можно оптимизировать этот код с 2D коллизиями?

обновлено до версии 1.5
теперь полноценно можно заспавнить 50 коробок и мерять свои фепосы
EN xgm.guru/files/100/315886/comments/520926/OMS_BoxLab_1.5_EN.w3x
RU xgm.guru/files/100/315886/comments/520926/OMS_BoxLab_1.5_RU.w3x
код 1.5 controlc.com/fce08fe1
дальше уже только оптимизация кода для повышения фпс
Загруженные файлы
14

» WarCraft 3 / Текстовый редактор триггеров

как вызвать текстовые триггеры как в примере ниже?
откуда вызвать?
они запускаются при старте карты через варик
F4 - клик триггер - правка - конвертировать в текст
14

» WarCraft 3 / Как можно оптимизировать этот код с 2D коллизиями?

Jack-of-shadow: Но там еще была загвоздка с тем, что весь террейн был разрушаемый. По этому при разрушении клетки
тут тоже самое, если кодом убрать под собой ландшафт, то все объекты полетят вниз пока не долетят до следующей твёрдой клетки
14

» WarCraft 3 / Как можно оптимизировать этот код с 2D коллизиями?

nazarpunk: лучше перебирать группы не через удаление юнита, а через ForGroup. Она к тому же создаёт псевдопоток, что позволяет обойти оплимит
попробовал накалякать через ForGroup
Открыть код и видео
globals
	integer MushroomMoving_CollisionCheck_i
	real MushroomMoving_CollisionCheck_x
	real MushroomMoving_CollisionCheck_y
	boolean array MushroomMoving_CollisionCheck_boo
endglobals

function MushroomMoving_CollisionCheck_ForGroup takes nothing returns nothing
	local unit u=GetEnumUnit()
	local integer j=0
	local real otherx
	local real othery
	local integer i = MushroomMoving_CollisionCheck_i
	local real x = MushroomMoving_CollisionCheck_x
	local real y = MushroomMoving_CollisionCheck_y
	if u!=OrangeMushroom[i] then
		set j=UnitIndex(u)
		if (GetPlayerSlotState(GetOwningPlayer(OrangeMushroom[j]))==PLAYER_SLOT_STATE_PLAYING or j>PLAYER_MAXINUM) and LevelClearState[j]==false then
			if MB_Frame_On==1 then
				set MB_CollisionY = MB_CollisionY+1
			endif
			set otherx=GetUnitX(OrangeMushroom[j])
			set othery=GetUnitY(OrangeMushroom[j])
			if ContainsCoords(otherx-64,othery-64,otherx+64,othery+64,x,y)==true then
				if PropellyCondition==true then
					if GetUnitTypeId(OrangeMushroom[j])!='orai' then
						set u=null
						set Frame_MainPlayerY=j
						set MushroomMoving_CollisionCheck_boo[i]=false
						return
					endif
				else
					set u=null
					set Frame_MainPlayerY=j
					set MushroomMoving_CollisionCheck_boo[i]=false
					return
				endif
			endif
		endif
	endif
	set u=null
	set MushroomMoving_CollisionCheck_boo[i]=true
	return
endfunction

function MushroomMoving_CollisionCheck takes integer i,real x,real y returns boolean
	local group G = CreateGroup()
	set MushroomMoving_CollisionCheck_i=i
	set MushroomMoving_CollisionCheck_x=x
	set MushroomMoving_CollisionCheck_y=y
	call GroupEnumUnitsInRange(G, x,y, 128, null)
	call ForGroup(G,function MushroomMoving_CollisionCheck_ForGroup)
	return MushroomMoving_CollisionCheck_boo[i]
	call DestroyGroup(G)
	set G=null
endfunction
коллизии начали кашлять
особенно в конце видео где 3 коробки - там видна рандомность - то стоит на коробке то проваливается


Jack-of-shadow: попробуй что то типо того:
сначала попробовал по аналогии с твоим кодом , только таймер в 100 раз меньше чем 0.02 = чтобы просчитать 100 коробок за 1 фрейм
call TriggerRegisterTimerEvent(t,0.0002,true)
и даже если коробок 10 а не 100, то просчитает всё за 10 тиков, а остальные 90 будет скипать
а call Frame__SquaresMoving(i) отключил, то есть Frame__SquaresMoving просчитывается отдельным кодом вообще
что должно сказаться на физике
Открыть код и скриншот
globals
	integer playersCurrectFrameOffset = 1
endglobals

function Frame__SquaresMoving2 takes nothing returns nothing
local integer i
	local real saveMaxG=-30
	local integer j=1
if playersCurrectFrameOffset <= PLAYER_MAXINUM+Stage_BoxsCount then
	set i = playersCurrectFrameOffset
	set Frame__SpeedX=8
	set Frame_MainPlayer=i
	if LevelClearState[i]==false then
		call Frame__MovingX(i,GetUnitX(OrangeMushroom[i]),GetUnitY(OrangeMushroom[i]))
		call Frame__MovingY(i,GetUnitX(OrangeMushroom[i]),GetUnitY(OrangeMushroom[i]))
		if s__StatusBorad_World[Status]>=6 then
			if IsUnitInRegion(Water_Rects,OrangeMushroom[i])==true then
				set saveMaxG=-10
			endif
		endif
		if GetUnitTypeId(OrangeMushroom[i])!='orai' then
			if Water_State[i]==true and DownArrow[i]==true then
				set gravity[i]=-15
			else
				if gravity[i]>saveMaxG then
					set gravity[i]=gravity[i]-2.0
				elseif gravity[i]<saveMaxG then
					set gravity[i]=saveMaxG
				endif
			endif
		endif
		if GetUnitTypeId(OrangeMushroom[i])!='orai' then
			if Frame__AccelerationCheck[i]==false then
				if Acceleration[i]!=0 then
					if Acceleration[i]>60 then
						set Acceleration[i]=60
					elseif Acceleration[i]>1 then
						set Acceleration[i]=Acceleration[i]-1
					elseif Acceleration[i]<-60 then
						set Acceleration[i]=-60
					elseif Acceleration[i]<-1 then
						set Acceleration[i]=Acceleration[i]+1
					else
						set Acceleration[i]=0
					endif
				endif
			else
				set Frame__AccelerationCheck[i]=false
			endif
		endif
	endif
        set playersCurrectFrameOffset = playersCurrectFrameOffset+1
endif	
endfunction

function Frame__SquaresMoving2Init takes nothing returns nothing
	local trigger t=CreateTrigger()
	call TriggerRegisterTimerEvent(t,0.0002,true)
	call TriggerAddAction(t,function Frame__SquaresMoving2)
endfunction 

function Frame__PlayersGroup takes nothing returns nothing
	local integer i=1
	if GravityChanger_Loading==false then
		set Frame__BoxState=false
		loop
			exitwhen i>PLAYER_MAXINUM
			if GetPlayerSlotState(Player(i-1))==PLAYER_SLOT_STATE_PLAYING then
				set Frame__OldX[i]=GetUnitX(OrangeMushroom[i])
				set Frame__OldY[i]=GetUnitY(OrangeMushroom[i])
			endif
			set i=i+1
		endloop
		set i=1
		loop
			exitwhen i>PLAYER_MAXINUM+Stage_BoxsCount
			if i<=PLAYER_MAXINUM then
				if GetPlayerSlotState(Player(i-1))==PLAYER_SLOT_STATE_PLAYING then
					if CinematicMode==false then
						if Observer_ViewNumber[i]==0 then
							if GravityChanger_State==false then
								call SetCameraTargetControllerNoZForPlayer(Player(i-1),OrangeMushroom[i],0,128,false)
							else
								call SetCameraTargetControllerNoZForPlayer(Player(i-1),OrangeMushroom[i],0,-128,false)
							endif
						else
							if GravityChanger_State==false then
								call SetCameraTargetControllerNoZForPlayer(Player(i-1),OrangeMushroom[Observer_ViewNumber[i]],0,128,false)
							else
								call SetCameraTargetControllerNoZForPlayer(Player(i-1),OrangeMushroom[Observer_ViewNumber[i]],0,-128,false)
							endif
						endif
					endif
					//call Frame__SquaresMoving(i)
				endif
			else
				set Frame__BoxState=true
				//call Frame__SquaresMoving(i)
			endif
			set i=i+1
		endloop
		set Frame__BoxState=false
		set i=1
		loop
			exitwhen i>PLAYER_MAXINUM+Stage_BoxsCount
			if i<=PLAYER_MAXINUM then
				if GetPlayerSlotState(Player(i-1))==PLAYER_SLOT_STATE_PLAYING then
					if CinematicMode==false then
						call BackGroundMove(i,Frame__OldX[i],Frame__OldY[i])
					endif
					set Frame__PropellyState[i]=false
					set Frame__GravityState[i]=false
					if NameTextTag[i]!=null then
						if GravityChanger_State==false then
							call SetTextTagPos(NameTextTag[i],GetUnitX(OrangeMushroom[i])-50,GetUnitY(OrangeMushroom[i])-120,0)
						else
							call SetTextTagPos(NameTextTag[i],GetUnitX(OrangeMushroom[i])+50,GetUnitY(OrangeMushroom[i])+120,0)
						endif
					endif
					call Jumper_Main(i)
					if s__StatusBorad_World[Status]==6 and IsPointInRegion(Arrow_AllRects,GetUnitX(OrangeMushroom[i]),GetUnitY(OrangeMushroom[i]))then
						call Arrow_SecretAction(i)
					endif
				endif
			else
				if Stage_BoxsCount !=0 then
					set Frame__PropellyState[i]=false
					set Frame__GravityState[i]=false
					call Jumper_Main(i)
					if s__StatusBorad_World[Status]==6 and IsPointInRegion(Arrow_AllRects,GetUnitX(OrangeMushroom[i]),GetUnitY(OrangeMushroom[i]))then
						call Arrow_SecretAction(i)
					endif
				endif
			endif
			set i=i+1
		endloop
	endif
endfunction

function main takes nothing returns nothing
call Frame__SquaresMoving2Init()
endfunction
но чё то не завелось, гриб на старте висит в воздухе и не ходит


зато твоя идея
+ этот пост:
nazarpunk: Условно хаотично бывает в асинхронных языках, где ты в жассе нашёл асинхронность?
натолкнули меня на ещё более простое и легко встраиваемое решение через TriggerEvaluate
Открыть код
globals
	trigger Frame__SquaresMoving3Trg = CreateTrigger()
	integer playersCurrectFrameOffset = 1
endglobals

function Frame__SquaresMoving3Act takes nothing returns boolean
local integer i=playersCurrectFrameOffset
	local real saveMaxG=-30
	local integer j=1
	set Frame__SpeedX=8
	set Frame_MainPlayer=i
	if LevelClearState[i]==false then
		call Frame__MovingX(i,GetUnitX(OrangeMushroom[i]),GetUnitY(OrangeMushroom[i]))
		call Frame__MovingY(i,GetUnitX(OrangeMushroom[i]),GetUnitY(OrangeMushroom[i]))
		if s__StatusBorad_World[Status]>=6 then
			if IsUnitInRegion(Water_Rects,OrangeMushroom[i])==true then
				set saveMaxG=-10
			endif
		endif
		if GetUnitTypeId(OrangeMushroom[i])!='orai' then
			if Water_State[i]==true and DownArrow[i]==true then
				set gravity[i]=-15
			else
				if gravity[i]>saveMaxG then
					set gravity[i]=gravity[i]-2.0
				elseif gravity[i]<saveMaxG then
					set gravity[i]=saveMaxG
				endif
			endif
		endif
		if GetUnitTypeId(OrangeMushroom[i])!='orai' then
			if Frame__AccelerationCheck[i]==false then
				if Acceleration[i]!=0 then
					if Acceleration[i]>60 then
						set Acceleration[i]=60
					elseif Acceleration[i]>1 then
						set Acceleration[i]=Acceleration[i]-1
					elseif Acceleration[i]<-60 then
						set Acceleration[i]=-60
					elseif Acceleration[i]<-1 then
						set Acceleration[i]=Acceleration[i]+1
					else
						set Acceleration[i]=0
					endif
				endif
			else
				set Frame__AccelerationCheck[i]=false
			endif
		endif
	endif
return false
endfunction 

function Frame__SquaresMoving3Init takes nothing returns nothing
	call TriggerAddCondition(Frame__SquaresMoving3Trg, Condition(function Frame__SquaresMoving3Act))
endfunction

function Frame__PlayersGroup takes nothing returns nothing
	local integer i=1
	if GravityChanger_Loading==false then
		set Frame__BoxState=false
		loop
			exitwhen i>PLAYER_MAXINUM
			if GetPlayerSlotState(Player(i-1))==PLAYER_SLOT_STATE_PLAYING then
				set Frame__OldX[i]=GetUnitX(OrangeMushroom[i])
				set Frame__OldY[i]=GetUnitY(OrangeMushroom[i])
			endif
			set i=i+1
		endloop
		set i=1
		loop
			exitwhen i>PLAYER_MAXINUM+Stage_BoxsCount
			set playersCurrectFrameOffset=i
			if i<=PLAYER_MAXINUM then
				if GetPlayerSlotState(Player(i-1))==PLAYER_SLOT_STATE_PLAYING then
					if CinematicMode==false then
						if Observer_ViewNumber[i]==0 then
							if GravityChanger_State==false then
								call SetCameraTargetControllerNoZForPlayer(Player(i-1),OrangeMushroom[i],0,128,false)
							else
								call SetCameraTargetControllerNoZForPlayer(Player(i-1),OrangeMushroom[i],0,-128,false)
							endif
						else
							if GravityChanger_State==false then
								call SetCameraTargetControllerNoZForPlayer(Player(i-1),OrangeMushroom[Observer_ViewNumber[i]],0,128,false)
							else
								call SetCameraTargetControllerNoZForPlayer(Player(i-1),OrangeMushroom[Observer_ViewNumber[i]],0,-128,false)
							endif
						endif
					endif
					call TriggerEvaluate(Frame__SquaresMoving3Trg)
				endif
			else
				set Frame__BoxState=true
				call TriggerEvaluate(Frame__SquaresMoving3Trg)
			endif
			set i=i+1
		endloop
		set Frame__BoxState=false
		set i=1
		loop
			exitwhen i>PLAYER_MAXINUM+Stage_BoxsCount
			if i<=PLAYER_MAXINUM then
				if GetPlayerSlotState(Player(i-1))==PLAYER_SLOT_STATE_PLAYING then
					if CinematicMode==false then
						call BackGroundMove(i,Frame__OldX[i],Frame__OldY[i])
					endif
					set Frame__PropellyState[i]=false
					set Frame__GravityState[i]=false
					if NameTextTag[i]!=null then
						if GravityChanger_State==false then
							call SetTextTagPos(NameTextTag[i],GetUnitX(OrangeMushroom[i])-50,GetUnitY(OrangeMushroom[i])-120,0)
						else
							call SetTextTagPos(NameTextTag[i],GetUnitX(OrangeMushroom[i])+50,GetUnitY(OrangeMushroom[i])+120,0)
						endif
					endif
					call Jumper_Main(i)
					if s__StatusBorad_World[Status]==6 and IsPointInRegion(Arrow_AllRects,GetUnitX(OrangeMushroom[i]),GetUnitY(OrangeMushroom[i]))then
						call Arrow_SecretAction(i)
					endif
				endif
			else
				if Stage_BoxsCount !=0 then
					set Frame__PropellyState[i]=false
					set Frame__GravityState[i]=false
					call Jumper_Main(i)
					if s__StatusBorad_World[Status]==6 and IsPointInRegion(Arrow_AllRects,GetUnitX(OrangeMushroom[i]),GetUnitY(OrangeMushroom[i]))then
						call Arrow_SecretAction(i)
					endif
				endif
			endif
			set i=i+1
		endloop
	endif
endfunction

function main takes nothing returns nothing
	call Frame__SquaresMoving3Init()
endfunction
теперь варик не захлёбывается, ник не отклеивается, и каждый гриб(ящик) просчитывается отдельным потоком с сохранением физики
макс количество коробок поднялось до 50+ и уже упирается всё в fps
-box1 поднялось с 11(v1.0) 14(v1.4) до 22 (выше тоже можно но фпс ниже 20)
-box3 поднялось с 11(v1.0) 25(v1.4) до 35 (20 фпс)
при отключении -pro режима фпс вырастет с 20 до 40
теперь осталось причесать код (указанные выше UnitIndex и global G) и опять обновлять версию
а если найти ошибки в 1 и 2 варианте выше в этом посте то и сравнить на скорость и фпс все 3 способа
Загруженные файлы
14

» WarCraft 3 / Как можно оптимизировать этот код с 2D коллизиями?

nazarpunk: лучше перебирать группы не через удаление юнита, а через ForGroup. Она к тому же создаёт псевдопоток, что позволяет обойти оплимит.
а как передать переменные внутрь ForGroup? а потом еще и вернуть результат? она же вызывается с takes nothing returns nothing
для этого создавать новый вопрос с тестовым мини кодом?
делать на глобалках? или на той же ht? а они разве не перезапишутся, если несколько ForGroup будут выполняться в разных тредах и перезаписывать результат в одну свою глобалку на true/false условно хаотично
или если ты в 3 глобалки (или в 3 значения в ht) записываешь входящие i , x , y - то они тоже будут прыгать при вызове MushroomMoving_CollisionCheck\ForGroup несколько раз т.к. идёт перезапись входящих общих переменных i x y при каждом их вызове
Открыть код
function UnitIndex takes unit u returns integer
	local integer i=1
	loop
		exitwhen i>PLAYER_MAXINUM+Stage_BoxsCount
		if u==OrangeMushroom[i] then
			set u=null
			return i
		endif
		set i=i+1
	endloop
	set u=null
	return 0
endfunction

function MushroomMoving_CollisionCheck_ForGroup takes nothing returns nothing
	local unit u=null
	local integer j=0
	local real otherx
	local real othery
	set u = GetEnumUnit()
	if u!=OrangeMushroom[i] then
		set j=UnitIndex(u)
		if (GetPlayerSlotState(GetOwningPlayer(OrangeMushroom[j]))==PLAYER_SLOT_STATE_PLAYING or j>PLAYER_MAXINUM) and LevelClearState[j]==false then
			if MB_Frame_On==1 then
				set MB_CollisionY = MB_CollisionY+1
			endif
			set otherx=GetUnitX(OrangeMushroom[j])
			set othery=GetUnitY(OrangeMushroom[j])
			if ContainsCoords(otherx-64,othery-64,otherx+64,othery+64,x,y)==true then
				if PropellyCondition==true then
					if GetUnitTypeId(OrangeMushroom[j])!='orai' then
						set u=null
						set Frame_MainPlayerY=j
						return false
					endif
				else
					set u=null
					set Frame_MainPlayerY=j
					return false
				endif
			endif
		endif
	endif
	set u=null
	return true
endfunction

function MushroomMoving_CollisionCheck takes integer i,real x,real y returns boolean
	local group G = CreateGroup()
	call GroupEnumUnitsInRange(G, x,y, 128, null)
	call ForGroup(G,function MushroomMoving_CollisionCheck_ForGroup)
	call DestroyGroup(G)
	set G=null
endfunction
Jack-of-shadow: попробуй что то типо того:
попробую и это решение, думаю колупаться долго буду со всем этим чтобы завести и протестировать оба решения
14

» WarCraft 3 / Всем привет. Как найти путь до модели *mdx ?

Smeto
models\hero\HeroGlow.mdx (Как узнать этот путь?)
anufis\dungeonrunners\effect\Crusade1.mdx (Как я могу узнать, этот путь если нет файлика Readme?)
хотел импортировать модель FleshTearer2.mdx
где все эти 3 модели в атаче?
зачем ты приложил пустой HeroGlow.mdx без текстур?
14

» WarCraft 3 / Wow.export с русскоязычными базами

при обращении к архивам casc можно выбирать язык локализации на базовом уровне
14

» WarCraft 3 / Как можно оптимизировать этот код с 2D коллизиями?

goodlyhero: Впринципе, период тут можно сильно повысить с 0.02. Даже если вы будете проверять коллизии с частотой 0.1, производительность поднимется в пять раз.
я уже пробовал менять это значение - ничего не меняется по нагрузке и по фпс
(да и любой из вас его может изменить за пол минуты и чекнуть результат - www.epicwar.com/maps/332635 вот новая версия карты 1.4 с добавленным радиусным ускорением )
это чисто лимит варкрафта на колво вложенных циклов и операций в одном стеке
единственное что из похожего помогает уменьшить тормоза и поднять фпс - это ириновский !actioninterval
nazarpunk: На каждого юнита вызывается UnitIndex. Тоесть лишний цикл на количество игроков. Можно просто каждому грибу записать его индекс через SetUnitUserData. Будет дешевле.
Очищать глобальную группу G дешевле, чем дрочить создание/удаление локалки.
замечания хорошие, нужно тестировать всякие наносекунды - сколько на практике это добавляет тормозов
nazarpunk: Удаление из группы происходит за O(n), поэтому лучше перебирать группы не через удаление юнита, а через ForGroup. Она к тому же создаёт псевдопоток, что позволяет обойти оплимит.
о, ради такого уже стоит вернуться к коду и протестировать, возможно это и будет тем решением о котором я и писал с самого начала - не изменяя логики кода пустить отдельным потоком просчет коллизий
nazarpunk: Этой проверки я так и не понял.
GetUnitTypeId(OrangeMushroom[i])!='orai'
это если юнит не самолётик. там есть самолетики которые сами по себе летают и имеют особые условия по физике, например отсутствие гравитации или способность возить других на своем борту
Jack-of-shadow: можно через хеш урезать до одной строки. cjass
это всё хорошо, только war3 не понимает cjass, можно хоть на си шарпе, питоне или джаве писать в пол строки и козырять этим - только компилятор все равно переведёт в обычный многострочный jass, это разве не очевидно?
Jack-of-shadow: В Frame__Main/BossMoving тоже что то жеское
ничего там нету жесткого, там сразу выход из функции по первому условию - if FinalStage==true and BlackBoss !=null
это всё мелочи, обычный код не нагружает варик в щщщи
то есть какой смысл оптимизировать чужой код (который в новых версиях карты вообще обфусцирован) ради наносекунд или уменьшения в каком-то месте с 5 строк до 3, когда уже выявлена реальная причина тормозов - это количество коробок и их обсчёт коллизий
нагружают именно коллизии и как уже выше было сказано - вложенный квадратичный (а теперь уже радиусный) цикл по ним
14

» XGM Team / Онлайн-инструменты для геймдев и моддинг арта

nazarpunk: погоду можно таким же тупым образом отловить если скинешь код её установки.
код установки погоды был в этом посте
технически нужно просто в WE создать 21 рект с разными погодами и после сохранения карты глянуть w3r и j
Открыть
    set gg_rct________________000 = Rect( -2784.0, -3200.0, -2496.0, -2976.0 )
    set gg_rct________________001 = Rect( -2240.0, -3200.0, -1920.0, -2976.0 )
    set we = AddWeatherEffect( gg_rct________________001, 'RAhr' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________002 = Rect( -1696.0, -3200.0, -1344.0, -2976.0 )
    set we = AddWeatherEffect( gg_rct________________002, 'RAlr' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________003 = Rect( -1120.0, -3232.0, -832.0, -3008.0 )
    set we = AddWeatherEffect( gg_rct________________003, 'MEds' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________004 = Rect( -608.0, -3232.0, -288.0, -3040.0 )
    set we = AddWeatherEffect( gg_rct________________004, 'FDbh' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________005 = Rect( -128.0, -3296.0, 224.0, -3040.0 )
    set we = AddWeatherEffect( gg_rct________________005, 'FDbl' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________006 = Rect( 480.0, -3296.0, 800.0, -3040.0 )
    set we = AddWeatherEffect( gg_rct________________006, 'FDgh' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________007 = Rect( 1120.0, -3296.0, 1408.0, -3040.0 )
    set we = AddWeatherEffect( gg_rct________________007, 'FDgl' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________008 = Rect( 1600.0, -3296.0, 1888.0, -3008.0 )
    set we = AddWeatherEffect( gg_rct________________008, 'FDrh' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________009 = Rect( 2112.0, -3296.0, 2400.0, -3040.0 )
    set we = AddWeatherEffect( gg_rct________________009, 'FDrl' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________010 = Rect( -2848.0, -2752.0, -2560.0, -2496.0 )
    set we = AddWeatherEffect( gg_rct________________010, 'FDwh' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________011 = Rect( -2336.0, -2784.0, -1952.0, -2496.0 )
    set we = AddWeatherEffect( gg_rct________________011, 'FDwl' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________012 = Rect( -1728.0, -2784.0, -1440.0, -2528.0 )
    set we = AddWeatherEffect( gg_rct________________012, 'RLhr' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________013 = Rect( -1152.0, -2784.0, -928.0, -2560.0 )
    set we = AddWeatherEffect( gg_rct________________013, 'RLlr' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________014 = Rect( -640.0, -2816.0, -352.0, -2560.0 )
    set we = AddWeatherEffect( gg_rct________________014, 'SNbs' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________015 = Rect( -128.0, -2848.0, 192.0, -2560.0 )
    set we = AddWeatherEffect( gg_rct________________015, 'SNhs' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________016 = Rect( 448.0, -2816.0, 704.0, -2560.0 )
    set we = AddWeatherEffect( gg_rct________________016, 'SNls' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________017 = Rect( 1088.0, -2816.0, 1344.0, -2528.0 )
    set we = AddWeatherEffect( gg_rct________________017, 'LRaa' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________018 = Rect( 1664.0, -2816.0, 1824.0, -2528.0 )
    set we = AddWeatherEffect( gg_rct________________018, 'LRma' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________019 = Rect( 2176.0, -2848.0, 2400.0, -2560.0 )
    set we = AddWeatherEffect( gg_rct________________019, 'WNcw' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________020 = Rect( 2656.0, -2880.0, 2816.0, -2528.0 )
    set we = AddWeatherEffect( gg_rct________________020, 'WOcw' )
    call EnableWeatherEffect( we, true )
    set gg_rct________________021 = Rect( 3008.0, -2848.0, 3200.0, -2560.0 )
    set we = AddWeatherEffect( gg_rct________________021, 'WOlw' )
    call EnableWeatherEffect( we, true )
и то оказывается была не цветопогода, а просто цвет, а погода идёт перед ним чистым равкодом
Загруженные файлы
14

» WarCraft 3 / Как можно оптимизировать этот код с 2D коллизиями?

Jack-of-shadow: Как часто вызывается MushroomMoving_CollisionCheck?
счетчика на колво вызовов самой функции нету
но есть счетчик по вызову GetUnitX() GetUnitY() - это цикл внутри MushroomMoving_CollisionCheck
на графиках это CPS
средние цифры - десятки тысяч раз в 1 сек
и счётчик отображается внутри карты тоже через -pro
Jack-of-shadow: В таком случае можно было бы разбить это со сдвигом во времени.
в движке полностью всё с нуля написано, и "время" в том числе
а проблема во вложенных циклах с лупом
14

» XGM Team / Онлайн-инструменты для геймдев и моддинг арта

nazarpunk: Подожди минут 10
а чего ждать? файл же верно формируется - как в 1ом варианте с зелеными областями
т.е. лучше вроде бы и некуда
nazarpunk: Добавил версию в title. Обновилось.
перекачал, w3r формируется такой же как в этом сообщении
только если раньше он скачивался только на вин10 - то теперь и на вин7 и на вин10
14

» XGM Team / Онлайн-инструменты для геймдев и моддинг арта

nazarpunk: Обновил
вин7 + хром 109.0.5414.120 - работает, скачивается
файл на 100% идентичен первому варианту (который был для вин10)
14

» XGM Team / Онлайн-инструменты для геймдев и моддинг арта

nazarpunk: Проверяй.
вин7 + хром 109.0.5414.120 - работает, скачивается
теперь вместо ярко-зеленых прямоугольников стоят бледно розовые
по хексу (в том месте где прописывается цветопогода) - в прошлой первой версии было 11 D9 33 FF, сейчас стало FF 33 D9 11
в остальных (нецветопогодных) местах файлы идентичные
Загруженные файлы
14

» WarCraft 3 / Как можно оптимизировать этот код с 2D коллизиями?

goodlyhero: Она отрезается условием, но полный перебор с проверкой этой штуки все равно происходит
добавил группу в расчёт по X, количество коллизий сократилось ещё на треть, фпс остался примерно таким же,
макс количество коробок в -box3 режиме выросло на 10%
конечный код:
Открыть
function UnitIndex takes unit u returns integer
	local integer i=1
	loop
		exitwhen i>PLAYER_MAXINUM+Stage_BoxsCount
		if u==OrangeMushroom[i] then
			set u=null
			return i
		endif
		set i=i+1
	endloop
	set u=null
	return 0
endfunction
function MushroomMoving_Collision takes integer i,real x,real y returns integer
	local integer j=1
	local real otherx
	local real othery
	local group G = CreateGroup()
	local unit u=null
	call GroupEnumUnitsInRange(G, x,y, 128, null)
	loop
		set u = FirstOfGroup(G)
		exitwhen u==null
		if u!=OrangeMushroom[i] then
			set j=UnitIndex(u)
			if (GetPlayerSlotState(GetOwningPlayer(OrangeMushroom[j]))==PLAYER_SLOT_STATE_PLAYING or j>PLAYER_MAXINUM) and WhetherCollision[j]==0 and LevelClearState[j]==false then
				if MB_Frame_On==1 then
					set MB_CollisionX = MB_CollisionX+1
				endif
				set otherx=GetUnitX(OrangeMushroom[j])
				set othery=GetUnitY(OrangeMushroom[j])
				if ContainsCoords(otherx-64,othery-64,otherx+64,othery+64,x,y)==true then
					if GetUnitTypeId(OrangeMushroom[i])!='orai' and GetUnitTypeId(OrangeMushroom[j])!='orai' then
						if LeftArrow[Frame_MainPlayer]==true and Acceleration[Frame_MainPlayer]<=0 then
							set WhetherCollision[j]=-1
						elseif RightArrow[Frame_MainPlayer]==true and Acceleration[Frame_MainPlayer]>=0 then
							set WhetherCollision[j]=1
						else
							set WhetherCollision[j]=0
						endif
					endif
					set u=null
					call DestroyGroup(G)
					set G=null
					return j
				endif
			endif
		endif
		call GroupRemoveUnit(G, u)
	endloop
	call DestroyGroup(G)
	set G=null
	return 0
endfunction
function MushroomMoving_CollisionCheck takes integer i,real x,real y returns boolean
	local integer j=1
	local real otherx
	local real othery
	local group G = CreateGroup()
	local unit u=null
	call GroupEnumUnitsInRange(G, x,y, 128, null)
	loop
		set u = FirstOfGroup(G)
		exitwhen u==null
		if u!=OrangeMushroom[i] then
			set j=UnitIndex(u)
			if (GetPlayerSlotState(GetOwningPlayer(OrangeMushroom[j]))==PLAYER_SLOT_STATE_PLAYING or j>PLAYER_MAXINUM) and LevelClearState[j]==false then
				if MB_Frame_On==1 then
					set MB_CollisionY = MB_CollisionY+1
				endif
				set otherx=GetUnitX(OrangeMushroom[j])
				set othery=GetUnitY(OrangeMushroom[j])
				if ContainsCoords(otherx-64,othery-64,otherx+64,othery+64,x,y)==true then
					if PropellyCondition==true then
						if GetUnitTypeId(OrangeMushroom[j])!='orai' then
							set u=null
							call DestroyGroup(G)
							set G=null
							set Frame_MainPlayerY=j
							return false
						endif
					else
						set u=null
						call DestroyGroup(G)
						set G=null
						set Frame_MainPlayerY=j
						return false
					endif
				endif
			endif
		endif
		call GroupRemoveUnit(G, u)
	endloop
	call DestroyGroup(G)
	set G=null
	return true
endfunction
14

» World of WarCraft / Blizzard анонсировала сразу три дополнения для World of Warcraft

The Last Titan — дополнение, в котором игроки вернутся в Нордскол и даже посетят Ульдуар, чтобы раскрыть тайну титанов.
ухты, никогда такого не было
14

» WarCraft 3 / какие свойства есть у абилки 'Aloc' и чем их воспроизвести?

а может есть какая-нибудь абилка невидимости без изменения прозрачности юнита?
чтобы убрать конкретного юнита с миникарты, но оставить его вид таким же
и еще так и не было инфы про "спец значок" и каким кодом это можно сделать
14

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

ага, получилось
векторная маска xgm.guru/files/100/316064/comments/520550/ps_mask.png
забавно что стало 514 цветов вместо оригинальных 294+1
т.е. по классике всю картинку фотошоп завандалил и поменял пиксели
чего кстати не произошло после обычного ресейва - там 294 осталось xgm.guru/files/100/316064/comments/520550/ps_resave.png

вот еще до кучи файлы
белый и черный альфа канал (2 и 3 пик из шапки)
но белый тоже завандаленный получается - там белый абрис формируется (виден при добавлении на карту)
черный xgm.guru/files/100/316064/comments/520550/as_black.png
белый xgm.guru/files/100/316064/comments/520550/cap-white.png
Загруженные файлы
14

» XGM Team / Онлайн-инструменты для геймдев и моддинг арта

виртуалку 10 накатил
Открыть
кстати в винде 10 22H2 идёт всего лишь 98й Edge
а 111й вышел в марте 2к23
график выхода версий

nazarpunk: Проверяй
тупой парсер превратил такой код
    set gg_rct_Rect001 = Rect( 576.0, 832.0, 704.0, 960.0 )
    set gg_rct_Rect002 = Rect( 192.0, 192.0, 448.0, 800.0 )
    set gg_rct_Rect003 = Rect( 544.0, 128.0, 1312.0, 448.0 )
    set Rect004 = Rect(100, 300, 500, 600)
    set Wr = Rect(100, 1100, 500, 1500)
в такой текст
Rect001 (576, 832, 704, 960)
Rect002 (192, 192, 448, 800)
Rect003 (544, 128, 1312, 448)
Rect004 (100, 300, 500, 600)
Wr (100, 1100, 500, 1500)
и в такие ректы зеленого цвета:
(6й рект Область005 на картинке для сравнения дефолтного цвета)
получается что совсем и не тупой, а очень полезный
даже сам преобразовал неверные числа в верные по делителю 32 (100 в 96, 500 в 512 итд)
Загруженные файлы
14

» XGM Team / Онлайн-инструменты для геймдев и моддинг арта

nazarpunk: который только в 111 хроме появился, так что обнови бразер
понели вас, перезвоним, оставайтися на линии
разговор на эту тему между нами уже был в теме про томл, так что ответы знаю заранее
а парсинг текста теперь хорошо работает, видит названия переменных любые и даже без gg_rct_
накачу виртуалку за часик
Загруженные файлы
14

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

Alan_Gu: Так блпЛаб и отображает твоею .пнг чисто
только нужно нажать на галочку "отобразить прозрачность".
так это понятно, это отображено в шапке на пиках 4 и 5
это же альфа канал - он и определяет прозрачность
Alan_Gu: Тот же пейнт отобразит ее просто белым цветом
пеинт вообще не умеет работать с прозрачностью
и при пересохранении в png вообще удаляет альфа кана и заливает белым
а не "просто отобразит белым"
Alan_Gu: А всякие артефакты как у тебя на первом скрине возникают, когда программа пытается заполнить прозрачную область.
Но это уже зависит от формата изображения и софта, где просматривается изображение - как я думаю.
это не артефакты лол
это не рандом
просто BLP LAB чуть ли не единственная прога которая показывает цвет этого альфа канала, остальные проги тупо прозрачное показывают
у каждого пикселя есть или нету альфа канал, а также есть цвет этого альфа канала
у меня это зависит от конкретных программ
пик 1 и пик 2 я могу легко сделать - заранее пересохраняя в определенных программах
и знаю какой цвет получится, просто потому что у них по дефолту альфа каналу придается свой цвет (черный или белый)
ну это как футболка разного цвета не перестаёт быть футболкой
имеющийся у меня софт может менять цвет альфа в принципе на любой xgm.guru/files/100/316064/comments/520543/11111_orange.png
НО ТОЛЬКО в режиме палитры, а в пнг палитра максимум 256 цветов
что отобразится на качестве картинки
нужно чтобы True Color был
вот я и спрашиваю какой софт умеет менять цвет альфа канала, при этом не теряя саму прозрачность или режим цветности картинки
Alan_Gu: максимум, чего я добился это вот:
В фотошопе сделал. Залил фон синим цветом и добавил альфа-маску там, где раньше была прозрачность и экспортировал обратно.
а можно более подробный гайд всего этого дела? шо жать там и в какой очередности?
с фотошопом вообще странное дело - почему он не показывает слой прозрачности, который есть там изначально при открытии картинки
а позволяет только создать свой новый альфа канал без отображения уже имеющегося альфа канала
это настораживает
после ресейва исходника в фотошопе выглядит забавно
14

» XGM Team / Онлайн-инструменты для геймдев и моддинг арта

nazarpunk: Проверяй
по нажатию кнопки ничего не происходит (файл не добавляется в скачку) (хром 109.0.5414.120) (edge 109.0.1518.78)
с дизайна кнопки орнул, топ
14

» WarCraft 3 / какие свойства есть у абилки 'Aloc' и чем их воспроизвести?

nazarpunk: Не все переборы москитов скипают.
МрачныйВорон делал исследование на эту тему:
МрачныйВорон: xgm.guru/p/wc3/191764/comments/view/350987
была тема о том что нативки которые начинают с GroupEnum....могут не выделять москитов в группу
правда, не все функции. посмотрите код/карту внимательно, сюда добавил все существующие в варе пики и проверял xgm.guru/p/wc3/187447?postid=345848#comment10
с помощью тех нативок GroupEnum..., которые ловят москитов, нельзя указать радиус.
МрачныйВорон: xgm.guru/p/wc3/187447/comments/view/345848
call GroupEnumUnitsInRange(g, x, y, 400., f) ловит всех юнитов, находящихся в радиусе от точке, но москитов не ловит
call GroupEnumUnitsInRangeCounted(g, x, y, 400., f, 4) аналогична GroupEnumUnitsInRange, но берет определенное кол-во юнитов. Москитов не ловит
call GroupEnumUnitsInRangeOfLoc(g, loc,400., f) аналогична GroupEnumUnitsInRange. Москитов не ловит.
call GroupEnumUnitsInRangeOfLocCounted(g, loc,400., f, 4) аналогична GroupEnumUnitsInRangeCounted. Москитов не ловит.
call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea ,f1) ловит всех юнитов в области. Москитов не ловит.
call GroupEnumUnitsInRectCounted(g,bj_mapInitialPlayableArea ,f1, 4) ловит определенное кол-во юнитов в области. Москитов не ловит.
call GroupEnumUnitsSelected(g,GetTriggerPlayer(),f) ловит юнитов. выделенным игроком. Москитов. очевидно. не ловит.
call GroupEnumUnitsOfPlayer(g,GetTriggerPlayer(),f1) ловит всех-всех юнитов игрока на карте. Москитов ловит нормально.
call GroupEnumUnitsOfType(g,"Peasant", f) ловит всех-всех юнитов с этим именем. Нужно писать английский аналог название (например работник = Peasant). Ловит москитов.
call GroupEnumUnitsOfTypeCounted(g,"Peasant", f, 4) ловит опреденное кол-во юнитов группу. Ловит Москитов.