set udg_Group = GetUnitsOfPlayerAll(Player(0))
Вот именно UnitsOfPlayer что-то создает и не удаляет, а мне это очень нужно чтобы выбирать юнитов с москитами, а триггеров в карте с их созданием оочень много и везде добавлять их в группу не варик
Триггер периодик, за 3 использования уже лагать начинает, поэтому надо убрать утечки
Вот именно UnitsOfPlayer что-то создает и не удаляет, а мне это очень нужно чтобы выбирать юнитов с москитами, а триггеров в карте с их созданием оочень много и везде добавлять их в группу не варик
Триггер периодик, за 3 использования уже лагать начинает, поэтому надо убрать утечки
Принятый ответ
Ну, Варкрафт 3 в целом не любит когда слишком много юнитов одновременно на экране, а если учитывать, что у них ещё возможно есть и модель, то графическая часть начинает сильно резать фпс, с этим особо ты ничего не сделаешь. По поводу твоего кода, слишком напоминает GUI особенно проверками, ниже как бы я написал, но так как это отрывок и нет пояснения что в целом код должен делать, то я не знаю сколь близко он выполнит твои цели/нужды.
Код
globals
timer gg_timer_Move = null
endglobals
function GetAxisAngle takes real fromX, real fromY, real targX, real targY returns real
return Rad2Deg( Atan2( targY - fromY, targX - fromX ) )
endfunction
function GetAxisDistance takes real castX, real fcastY, real targX, real targY returns real
return SquareRoot( Pow( targX - castX, 2 ) + Pow( fcastY - targY, 2 ) )
endfunction
function NewX takes real locX, real dist, real angle returns real
return locX + dist * Cos( Deg2Rad( angle ) )
endfunction
function NewY takes real locY, real dist, real angle returns real
return locY + dist * Sin( Deg2Rad( angle ) )
endfunction
function Move_GroupActionsHandler takes unit target returns nothing
local integer uid = GetUnitTypeId( target )
local real speed = 8 //скорость движения | Локальные переменные советую писать с маленькой буквы.
local real targX = GetUnitX( target ) // GetWidgetX не быстрее GetUnitX, не нужно этого делать :)
local real targY = GetUnitY( target ) // GetWidgetY не быстрее GetUnitY, не нужно этого делать :)
local real moveX = 0.
local real moveY = 0.
local real angle = 0.
if udg_Time >= 6000 then
if uid >= 'h044' and uid <= 'h046' then
call RemoveUnit( target )
else
call UnitDamageTargetBJ( udg_Caster, target, 2000., ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNKNOWN )
endif
else
if GetAxisDistance( udg_CasterX, udg_CasterY, targX, targY ) <= udg_Time / 10 * 8 then // Сделай один раз враппер и будет проще.
if RAbsBJ( targX ) <= 4000 and RAbsBJ( targY ) <= 4000 then //чтобы не двигал если юнит на краю карты | не нужно каждый раз читать местоположение по-новой.
if not IsUnitType( target, UNIT_TYPE_STRUCTURE ) and target != udg_Caster and target != udg_DummyCaster then
set angle = GetAxisAngle( udg_CasterX, udg_CasterY, targX, targY ) //угол между координатами кастера и коорд юнита | через враппер.
set moveX = NewX( moveX, speed, angle )
set moveY = NewY( moveY, speed, angle ) // В твоей же системе было с минусом, ибо угол считался от кастера, собственно, если нужно отталкивание, но нужен +, если что просто замени на -speed
if not IsTerrainPathable( moveX, moveY, PATHING_TYPE_FLYABILITY ) or uid == 'h045' or uid == 'h046' then // лучше в начале проверить есть ли смысл двигать или нет.
// + RAbsBJ( 50 ) дал бы не совсем правильные результаты, ибо координаты могут быть отрицательными...
if GetTerrainType( moveX, moveY ) != 'Jdrt' then
call SetTerrainType( moveX, moveY, 'Jdrt', -1, 1, 0 ) //если тип земли не изменен на этот, изменить его
endif
call SetUnitX( target, moveX ) //двигаем юнита
call SetUnitY( target, moveY )
endif
endif
endif
endif
endif
endfunction
function Move_GroupActions takes nothing returns nothing //двигаем всех юнитов от точки кастера??
call Move_GroupActionsHandler( GetEnumUnit( ) )
endfunction
function Move_Actions takes nothing returns nothing
local integer i = 0
local integer pid = GetOwningPlayer( udg_Caster )
if udg_Time == 0 then //в начале создаются даммики 45 штук...
loop
exitwhen i == 45
set udg_MoveAngle = i * 8.
set udg_Dummy[ i ] = CreateUnit( Player( pid ), 'h045', udg_CasterX - 200 * Cos( udg_MoveAngle ), udg_CasterY - 200 * Sin( udg_MoveAngle ), udg_MoveAngle )
set i = i + 1
endloop
if udg_Group == null then
set udg_Group = CreateGroup( )
endif
else
if udg_Time <= 6000 then
set i = 0
loop
exitwhen i > bj_MAX_PLAYERS // цикл всех игроков ничем не хуже...
if Player( i ) == PLAYER_SLOT_STATE_PLAYING then
call GroupEnumUnitsOfPlayer( udg_Group, Player( i ), null )
call ForGroup( udg_Group, function Move_GroupActions )
call GroupClear( udg_Group )
endif
set i = i + 1
endloop
else
call PauseUnit( udg_Caster, false )
call PauseTimer( gg_timer_Move )
endif
endif
set udg_Time = udg_Time + 10
endfunction
//===========================================================================
function InitTrig_Move takes nothing returns nothing
set gg_timer_Move = CreateTimer( )
call TimerStart( gg_timer_Move, .01, true, function Move_Actions )
endfunction
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован Undert4ker
set bj_lastCreatedGroup = CreateGroup()
loop
exitwhen i == bj_MAX_PLAYER_SLOTS
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup,Player(i),null)
call ForGroup(bj_lastCreatedGroup,function Filter)
set i = i + 1
endloop
call GroupClear(bj_lastCreatedGroup)
call DestroyGtoup(bj_lastCreatedGroup)
call DestroyGroup(udg_Group)
Отредактирован Lotus101
Bergi_Bear:
Так что лучше это PlayerAll не использовать. Всем спасибо.