khanat-client/ressources/scripts/square_cell.gd

153 lines
5 KiB
GDScript3
Raw Normal View History

extends Resource
#warning-ignore-all:unused_class_variable
const DIR_N = Vector3(0, 0, -1)
const DIR_NE = Vector3(1, 0, -1)
const DIR_E = Vector3(1, 0, 0)
const DIR_SE = Vector3(1, 0, 1)
const DIR_S = Vector3(0, 0, 1)
const DIR_SW = Vector3(-1, 0, 1)
const DIR_W = Vector3(-1, 0, 0)
const DIR_NW = Vector3(-1, 0, -1)
const DIR_ALL = [DIR_N, DIR_NE, DIR_E, DIR_SE, DIR_S, DIR_SW, DIR_W, DIR_NW]
var size = Vector3( 1, 1, 1 )
var coords = Vector3( 0, 0, 0 )
func _init( p_coords ):
if typeof(p_coords) == typeof(self):
p_coords = p_coords.coords
self.set_coords( p_coords )
func new_cell( p_coords ):
# Returns a new HexCell instance
return get_script().new( p_coords )
func set_coords( p_coords ):
self.coords = Vector3( int(p_coords.x), int(p_coords.y), int(p_coords.z) )
# self.coords = Vector3( floor(p_coords.x), floor(p_coords.y), floor(p_coords.z) )
func distance_to( p_coords ):
var a = p_coords.x - self.coords.x
var b = p_coords.y - self.coords.y
var c = p_coords.z - self.coords.z
var h = sqrt( a*a + b*b + c*c )
return int( h )
func cell_distance_to( p_coords ):
return max( abs(p_coords.x-self.coords.x), abs(p_coords.z-self.coords.z) )
func get_arc_area( p_distance, p_direction ):
var cells = Array()
if p_direction in [ DIR_N, DIR_S, DIR_E, DIR_W ]:
var old_x = 0
for x in range(1, p_distance):
var nb_z = old_x + x
for z in range( -ceil(nb_z/2)-1, floor(nb_z/2) ):
var cell = null
if p_direction == DIR_E:
cell = new_cell( self.coords+Vector3( x, 0, z+1 ) )
elif p_direction == DIR_W:
cell = new_cell( self.coords+Vector3( -x, 0, z+1 ) )
elif p_direction == DIR_N:
cell = new_cell( self.coords+Vector3( z+1, 0, -x ) )
elif p_direction == DIR_S:
cell = new_cell( self.coords+Vector3( z+1, 0, x ) )
if cell:
cells.push_back( cell )
old_x = x
else:
var old_x = 0
for x in range(1, p_distance+1):
for z in range( 0, p_distance ):
var cell = null
if p_direction == DIR_SW:
cell = new_cell( self.coords+Vector3( -x, 0, z+1 ) )
elif p_direction == DIR_NW:
cell = new_cell( self.coords+Vector3( -x, 0, -(z+1) ) )
elif p_direction == DIR_NE:
cell = new_cell( self.coords+Vector3( z+1, 0, -x ) )
elif p_direction == DIR_SE:
cell = new_cell( self.coords+Vector3( z+1, 0, x ) )
if cell:
cells.push_back( cell )
return cells
func get_ring( distance ):
var cells = Array()
for x in range( -distance+self.coords.x, distance+self.coords.x+1 ):
for z in range( -distance+self.coords.z, distance+self.coords.z+1 ):
var cell = new_cell( Vector3( x, 0, z ) )
if not cell.coords == self.coords and self.cell_distance_to( cell.coords ) == distance:
cells.push_back( cell )
return cells
func get_area( distance_max, distance_min = 0 ):
var cells = Array()
for x in range( -distance_max+self.coords.x, distance_max+self.coords.x+1 ):
for z in range( -distance_max+self.coords.z, distance_max+self.coords.z+1 ):
var cell = new_cell( Vector3( x, 0, z ) )
if not cell.coords == self.coords:
if self.cell_distance_to( cell.coords ) >= distance_min:
cells.push_back( cell )
return cells
func get_adjacent( direction ):
return self.new_cell(self.coords + direction)
func get_cells_adjacent():
var cells = Array()
for coord in DIR_ALL:
cells.append(new_cell(self.coords + coord))
return cells
static func get_dir_from_angle( p_angle ):
p_angle = int(p_angle) % 360
if p_angle < 0:
p_angle = 360 + p_angle
if (0 <= p_angle and p_angle < 22.5) or (337.5 <= p_angle and p_angle <= 360):
return DIR_N
elif 22.5 <= p_angle and p_angle < 67.5:
return DIR_NW
elif 67.5 <= p_angle and p_angle < 112.5:
return DIR_W
elif 112.5 <= p_angle and p_angle < 157.5:
return DIR_SW
elif 157.5 <= p_angle and p_angle < 202.5:
return DIR_S
elif 202.5 <= p_angle and p_angle < 247.5:
return DIR_SE
elif 247.5 <= p_angle and p_angle < 337.5:
return DIR_E
elif 292.5 <= p_angle and p_angle < 337.5:
return DIR_NE
return null
static func dir_to_str( p_dir ):
if p_dir == DIR_N:
return "N"
elif p_dir == DIR_NE:
return "NE"
elif p_dir == DIR_E:
return "E"
elif p_dir == DIR_SE:
return "SE"
elif p_dir == DIR_S:
return "S"
elif p_dir == DIR_SW:
return "SW"
elif p_dir == DIR_W:
return "W"
elif p_dir == DIR_NW:
return "NW"
else:
return "None"