Вопрос по поводу отлова точки
Есть простейшая способность с отталкиванием, так вот, хочу, чтобы когда юнит встречается с препятсвием(постройка/другой юнит/рельефные особенности), юнит прекращался свое движение. Пробую через IsTerrainPathable, ничего не выходит

Лучший ответ:
pro100master:
Надо погрешность учитывать, примерно 0.5 ед.
     boolean IsTerrainPathableTrue(real x, real y){
      boolean b = true
      SetUnitPosition  (PathableUnit,x,y) 
      if (RAbsBJ (GetUnitX(PathableUnit) - x)>0.5)or(RAbsBJ (GetUnitY(PathableUnit) - y)>0.5){
       b = false 
      }
      return b 
     }  
» PathableLib
 //Для работы библиотеки нужно:
    //1. Указать ид в переменной PathableUnitId
    //2. Инициализировать библиотеку PathableIni()
    library PathableLib
     globals
      private integer PathableUnitId = 'h000' //ид даммика
      private unit    PathableUnit
      private real    PathableX
      private real    PathableY
     endglobals 

     boolean IsTerrainPathableTrue(real x,real y){
      SetUnitPosition   (PathableUnit,x,y) 
      PathableX = GetUnitX(PathableUnit) - x
      PathableY = GetUnitY(PathableUnit) - y
      if PathableX <= 0 {PathableX = -PathableX} //RAbsBJ
      if PathableY <= 0 {PathableY = -PathableY} //RAbsBJ   
      return PathableX < 0.5 or PathableY < 0.5
     }  
      
     define IsTerrainPathableFalse(x,y) = not(IsTerrainPathableTrue(x,y))     
     
    nothing PathableIni(){ 
     PathableUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),PathableUnitId,0,0,0) 
     ShowUnit (PathableUnit, false)
    }
    
    endlibrary
    



Просмотров: 229

KaneThaumaturge #1 - 2 месяца назад 1
IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) - вернет true если местность непроходима, и false, если местность проходима.
quq_CCCP #2 - 2 месяца назад 1
KaneThaumaturge, эта функция инверсная, она вернет false если место проходимое.
Jack-of-shadow #3 - 2 месяца назад (отредактировано ) 0
IsTerrainPathable криво работает с разрушаемыми объектами.

Однако можно написать свою функцию на даммике, перемещая его в точку и проверяя его смещение относительно заданных координат.
KaneThaumaturge #4 - 2 месяца назад 1
и false, если местность проходима.
А я что написал, мм?
LainMikoroso #5 - 2 месяца назад 0
Jack-of-shadow:
IsTerrainPathable криво работает с разрушаемыми объектами.

Однако можно написать свою функцию на даммике, перемещая его в точку и проверяя его смещение относительно заданных координат.
Нууууу, вот это мне нравится, еще есть какие-нибудь варианты?(Кроме выбирания декора/юнитов в радиусе)
KaneThaumaturge #6 - 2 месяца назад 0
LainMikoroso, эта функция, скорее всего, самый оптимальный вариант, однако я раньше использовал IsTerrainPathable() и багов не встречал.
А, вспомнил, я не встречал багов, потому что использовал IsTerrainPathable() для остановки реактивного рывка, который разрушал все разрушаемые объекты на своем пути. По-этому, он просто не мог столкнутся с ними.
Bergi_Bear #7 - 2 месяца назад 1
function Out takes real x, real y returns boolean
    return ((GetRectMinX(bj_mapInitialPlayableArea)<=x)and(x<=GetRectMaxX(bj_mapInitialPlayableArea))and(​GetRectMinY(bj_mapInitialPlayableArea)<=y)and(y<=GetRectMaxY(bj_mapInitialPlayableArea))) or IsTerrainPathable(x,y, PATHING_TYPE_WALKABILITY)==false
endfunction
Только проверять нужно у точки впереди, сюда же можно добавить функцию проверки декора в точке
function CheckDes takes nothing returns nothing
local destructable d=GetEnumDestructable()
if GetDestructableLife(d)>0 and cdb==false  and d!=null then
set cdb=TRUE
endif
set d=null
endfunction

function PCD takes real x,real y, unit u returns boolean//PointConteintDes
local rect r
local real d=50
set r=Rect( x - d*2, y - d*2, x + d*2, y +d*2 )
set cdb=false
call EnumDestructablesInRect(r,null,function CheckDes)
call RemoveRect(r)
set r=null
return cdb
endfunction
где cdb - логическая глобалка
работает как часы со времён 2013
LainMikoroso #8 - 2 месяца назад 0
Bergi_Bear:
function Out takes real x, real y returns boolean
    return ((GetRectMinX(bj_mapInitialPlayableArea)<=x)and(x<=GetRectMaxX(bj_mapInitialPlayableArea))and(​GetRectMinY(bj_mapInitialPlayableArea)<=y)and(y<=GetRectMaxY(bj_mapInitialPlayableArea))) or IsTerrainPathable(x,y, PATHING_TYPE_WALKABILITY)==false
endfunction
Только проверять нужно у точки впереди, сюда же можно добавить функцию проверки декора в точке
function CheckDes takes nothing returns nothing
local destructable d=GetEnumDestructable()
if GetDestructableLife(d)>0 and cdb==false  and d!=null then
set cdb=TRUE
endif
set d=null
endfunction

function PCD takes real x,real y, unit u returns boolean//PointConteintDes
local rect r
local real d=50
set r=Rect( x - d*2, y - d*2, x + d*2, y +d*2 )
set cdb=false
call EnumDestructablesInRect(r,null,function CheckDes)
call RemoveRect(r)
set r=null
return cdb
endfunction
где cdb - логическая глобалка
работает как часы со времён 2013
Ой не, спасибо, каждый тик создавать регион и проверять, там выше куда приятнее и быстрее способ, через разницу в назначенной и нынешней точкой
Bergi_Bear #9 - 2 месяца назад 1
LainMikoroso, уж это точно не глючит не на секунду ни на 1 фпс
LainMikoroso #10 - 2 месяца назад 0
Bergi_Bear:
LainMikoroso, уж это точно не глючит не на секунду ни на 1 фпс
Суть не в том, что не глючит, у меня очень много объектов перемещается, и продуктивнее будет вариант с подсчетом, без создания хендлов.
Bergi_Bear #11 - 2 месяца назад 1
эта система терпела 1к объктов без лагов, подлагивали скорее всего сами объекты, но не система с этим регионом... но твоё дело не верить мне
LainMikoroso #12 - 2 месяца назад 0
Bergi_Bear:
эта система терпела 1к объктов без лагов, подлагивали скорее всего сами объекты, но не система с этим регионом... но твоё дело не верить мне
Хмммммммм, ну не знаю, попробую твою
Bergi_Bear #13 - 2 месяца назад 1
Думаю ты вроде соображаешь, можно не все типы декора проверять а только определённые или методом исключения, но тут ещё нет рельефных особенностей, надо проверять что точка резко стала выше, через
if d<=0 or Out(MoveX(x,s*2,a),MoveY(y,s*2,a))==false or GetPointZ(x,y)<=GetPointZ(MoveX(x,s*2,a),MoveY(y,s*2,a))-30  then
LainMikoroso #14 - 2 месяца назад 0
GetPointZ
GetPointZ Б-- А это откуда ты взял?
Maniac_91 #15 - 2 месяца назад 0
У меня есть наработка, если нужно. Только с уровнями местности не проверял: xgm.guru/p/blog-maniac91/push.
pro100master #16 - 2 месяца назад 0
как страно вы! Я тупо дамми юнит с радиус 1х1 и двигаю ему и чекаю позиция равен ли дамми если нет то проходимость отолкнули дамми. итог ясен!
SetUnitPos(u, x, y)
if GetUnitPosX(u) != x or GetUnitPosY(u) != y{
непрошел из за блокатор пути и его сместил куда то.
} else {
прошел
}
Jack-of-shadow #17 - 2 месяца назад (отредактировано ) 0

pro100master:
Надо погрешность учитывать, примерно 0.5 ед.
     boolean IsTerrainPathableTrue(real x, real y){
      boolean b = true
      SetUnitPosition  (PathableUnit,x,y) 
      if (RAbsBJ (GetUnitX(PathableUnit) - x)>0.5)or(RAbsBJ (GetUnitY(PathableUnit) - y)>0.5){
       b = false 
      }
      return b 
     }  
» PathableLib
 //Для работы библиотеки нужно:
    //1. Указать ид в переменной PathableUnitId
    //2. Инициализировать библиотеку PathableIni()
    library PathableLib
     globals
      private integer PathableUnitId = 'h000' //ид даммика
      private unit    PathableUnit
      private real    PathableX
      private real    PathableY
     endglobals 

     boolean IsTerrainPathableTrue(real x,real y){
      SetUnitPosition   (PathableUnit,x,y) 
      PathableX = GetUnitX(PathableUnit) - x
      PathableY = GetUnitY(PathableUnit) - y
      if PathableX <= 0 {PathableX = -PathableX} //RAbsBJ
      if PathableY <= 0 {PathableY = -PathableY} //RAbsBJ   
      return PathableX < 0.5 or PathableY < 0.5
     }  
      
     define IsTerrainPathableFalse(x,y) = not(IsTerrainPathableTrue(x,y))     
     
    nothing PathableIni(){ 
     PathableUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),PathableUnitId,0,0,0) 
     ShowUnit (PathableUnit, false)
    }
    
    endlibrary
    
прикреплены файлы