Re: Проверка на проходимость
Posted: 2011-07-13 14:27:35
Не подходит даже к fw, где углы простреливаются
Code: Select all
dx = endx - startx
dy = endy - starty
While x <> endx or y <> endy
If abs(dx) > abs(dy) then
If x <> startx + int(abs(dx) / abs(dy)) * Sign(dx) then
If dx > 0 then
x = x + 1
else
x = x - 1
Endif
else
startx = x ; Прошёл int(abs(dx) / abs(dy)) тайлов вперёд, делает шаг в сторону
If dy > 0 then
y = y + 1
else
y = y - 1
Endif
Endif
else
...
Endif
String = String + str(x) + ' ' + str(y) + ' ' ; Записываем тайл в строку
Value = Value + 1 ; Считаем кол-во тайлов
Wend
Return str(Value) + String
Sign(число) вернёт 1 если число положительное, -1 если отрицательное
Code: Select all
---ХХ
---Х-
--ХХ-
--Х--
-ХХ--
-Х---
ХХ---
Code: Select all
var DIR_N = 0
var DIR_NW = 7
var DIR_W = 6
var DIR_SW = 5
var DIR_S = 4
var DIR_SE = 3
var DIR_E = 2
var DIR_NE = 1
var AXIS_X = 0
var AXIS_Y = 1
sub Point( point, x, y, z )
point[0] = x
point[1] = y
point[2] = z
end sub
sub Point.toString( point )
return str( point[0] ) + ' ' + str( point[1] ) + ' ' + str( point[2] )
end sub
sub Point.createFromLastTile( point )
point[0] = UO.lastTile(1)
point[1] = UO.lastTile(2)
point[2] = UO.lastTile(3)
end sub
sub Point.createFromChar( point )
point[0] = UO.getX()
point[1] = UO.getY()
point[2] = UO.getZ()
end sub
sub Point.move( point, dir )
Point.moveN( point, dir, 1 )
end sub
sub Point.moveN( point, dir, dist )
var dx, dy
dx = Axis.getDirSign( AXIS_X, dir )
dy = Axis.getDirSign( AXIS_Y, dir )
point[0] = point[0] + dx*dist
point[1] = point[1] + dy*dist
end sub
sub Point.distance( spoint, dpoint )
var ax = Math.abs( spoint[0] - dpoint[0] )
var ay = Math.abs( spoint[1] - dpoint[1] )
return Math.max( ax, ay )
end sub
sub Point.getDir( spoint, dpoint )
var dx, dy
var ax, ay
var slope
dx = dpoint[0] - spoint[0]
dy = dpoint[1] - spoint[1]
ax = Math.abs( dx )
ay = Math.abs( dy )
if ( ay > ax ) then
if ( not ax ) then
return iif( dy < 0, DIR_N, DIR_S )
end if
slope = ay / ax
if ( slope > 2 ) then
return iif( dy < 0, DIR_N, DIR_S )
end if
if ( dx < 0 ) then
return iif( dy < 0, DIR_NW, DIR_SW )
end if
return iif( dy < 0, DIR_NE, DIR_SE )
else
if ( not ay ) then
if ( not ax ) then
return UO.getDir()
end if
return iif( dx < 0, DIR_W, DIR_E )
end if
slope = ax / ay
if ( slope > 2 ) then
return iif( dx < 0, DIR_W, DIR_E )
end if
if ( dy < 0 ) then
return iif( dx < 0, DIR_NW, DIR_NE )
end if
return iif( dx < 0, DIR_SW, DIR_SE )
end if
end sub
sub Axis.getDirSign( axis, dir )
dir = dir - 2*axis
if ( dir > 0 ) and ( dir < 4) then
return 1
else
return iif( ( dir == 0 ) or ( dir == 4 ), 0, -1 )
end if
end sub
sub Char.getDir( point )
dim p[3]
Point( p, UO.getX(), UO.getY(), 0 )
return Point.getDir( p, point )
end sub
sub Char.LOSVisualise( dpoint )
dim spoint[3]
var dir
Point.createFromChar( spoint )
UO.mfgi( "add", 1332, spoint[0], spoint[1], 0 )
while Point.distance( spoint, dpoint )
UO.print( 'in' )
dir = Point.getDir( spoint, dpoint )
UO.print( 'dir: ' + str( dir ) + ' point: ' + Point.toString( spoint ) )
Point.move( spoint, dir )
UO.print( 'move -> ' + Point.toString( spoint ) )
UO.exec( 'mfgi add 1332 ' + Point.toString( spoint ) )
UO.print( 'out' )
wend
end sub
sub Math.abs( x )
if x < 0 then
return -x
end if
return x
end sub
sub Math.max( x, y )
if x < y then
return y
end if
return x
end sub
sub iif( condition, trueValue, elseValue )
if ( condition ) then
return trueValue
end if
return elseValue
end sub
sub test()
dim dpoint[3]
var dir
UO.info()
while UO.targeting()
wait(100)
wend
Point.createFromLastTile( dpoint )
dir = Char.getDir( dpoint )
UO.print( str( UO.getDir() ) + ' ' + str( dir ) )
UO.print( 'x: ' + str( Axis.getDirSign( AXIS_X, dir ) ) + ' y: ' + str( Axis.getDirSign( AXIS_Y, dir ) ) )
Char.LOSVisualise( dpoint )
end sub
Grin wrote:Начнем с самого простого, понятие "траектория стрелы" - сервером не рассчитывается является только визуальным эффектом на стороне клиента. Сервером же рассчитывает ВОЗМОЖНОСТЬ из данной позиции поразить цель.
Grin wrote:Достаточно маломальский ознакомится сферой и увидеть... что оказывается конфигом предусмотрен выбор экспериментального алгоритма:) Проведя реверс, вы заметите что он отличается от РанУО не значительно...
Grin wrote:Что за бредовые попытки рассчитывать нечто не принимая во внимание исходные данные?:) Что бы ваши "алгоритмы" проверять нужно абсолютно чистое поле:) Вы даже не берете в расчет о существовании таких фундаментальных вещей как свойства объектов (флаги tiledata)... в некоторых конфигурациях стелы могут пролетать через окна:) не всякий предмет будет блокировать видимость, а еще у предметов есть высота:)
Grin wrote:Легко выбрать тайлы которые надо проверить, а вот как проверять то будете?:)
Grin wrote:И еще раз, у сеферы один алгоритм проверки, в 56б добавлен экспериментальный:)
Code: Select all
sub Point.getDir( spoint, dpoint )
var dx, dy
var ax, ay
var slope
dx = spoint[0] - dpoint[0]
dy = spoint[1] - dpoint[1]
ax = Math.abs( dx )
ay = Math.abs( dy )
if ( ay <= ax ) then
if ( not ay ) then
if ( not ax ) then
return UO.getDir()
end if
return iif( dx > 0, DIR_W, DIR_E )
end if
slope = int( ax / ay )
if ( slope > 2 ) then
return iif( dx > 0, DIR_W, DIR_E )
end if
if ( dy > 0 ) then
return iif( dx > 0, DIR_NW, DIR_NE )
end if
return iif( dx > 0, DIR_SW, DIR_SE )
end if
if ( ax ) then
slope = int( ay / ax )
if ( slope <= 2 ) then
if ( dx <= 0 ) then
return iif( dy <= 0, DIR_SE, DIR_NE )
else
return iif( dy > 0, DIR_NW, DIR_SW )
end if
end if
end if
return iif( dy > 0, DIR_N, DIR_S )
end sub
Code: Select all
// Uses the new LoS algorithm
// ADVANCEDLOS_DISABLED 0x00 // Disabled, use the old method
// ADVANCEDLOS_PLAYER 0x01 // Enabled only for players
// ADVANCEDLOS_NPC 0x02 // Enabled only for NPCs
AdvancedLos=0
Mirage wrote:выше было тестовым методом установлено что такой вариант работать не будет - при 1 клетке по диагонали тайл не проходим на сфере.