diff options
| -rw-r--r-- | Hex.gd | 14 | ||||
| -rw-r--r-- | HexBoard.gd | 55 | ||||
| -rw-r--r-- | Piece.gd | 11 | ||||
| -rw-r--r-- | Tile.gd | 15 | ||||
| -rw-r--r-- | Unit.gd | 12 | 
5 files changed, 106 insertions, 1 deletions
| @@ -37,7 +37,19 @@ func height() -> int:  	return 0  func elevation() -> int: -	if type == 2: return 2 +	if type == 2: return 3 +	return 0 + +func range_modifier(category : int) -> int: +	return (1 if type == 2 else 0) + +func attack_modifier(category : int, orientation : int) -> int: +	return (2 if type == 1 else 0) + +func defense_value(category : int, orientation : int) -> int: +	if type == 0: return 2 +	elif type == 1: return 1 +	elif type == 2: return 1  	return 0  func block_los(from : Tile, to : Tile, d : float, dt : float) -> bool: diff --git a/HexBoard.gd b/HexBoard.gd index 0bc6fa1..ab52dd6 100644 --- a/HexBoard.gd +++ b/HexBoard.gd @@ -92,6 +92,36 @@ func opposite(o : int) -> int:  	if o <= Orientation.NW: return o << 4  	return o >> 4 +# return the Orientation given to distant Tiles +# Orientation is combined in case of diagonals +func distant_orientation(from : Tile, to : Tile) -> int: +	var a : float = rad2deg((to.position - from.position).angle()) +	if a < 0: a += 360 +	a = int(a * 10) / 10.0 +	for k in angles.keys(): +		var z : int = angles[k] +		if a >= (z + 30 - DEGREE_ADJ) and a <= (z + 30 + DEGREE_ADJ): +			# diagonal +			var p : int = k >> 1 +			if p == 0: p = Orientation.SE +			if not angles.has(p): return k | p >> 1 # v : N S and not v : W E +			else: return (k | p) +		elif (z == 30 and (a < DEGREE_ADJ or a > 360 - DEGREE_ADJ)): +			return Orientation.NE | Orientation.SE +		elif a >= (z - 30) and a <= (z + 30): +			return k +	if angles.has(Orientation.E) and a > 330 and a <= 360: +		return Orientation.E +	return -1 + +# return the opposite of a possibly combined given Orientation +func distant_opposite(o : int) -> int: +	var r : int = 0 +	for k in angles.keys(): +		if (k & o) == k: +			r |= opposite(k) +	return r +  # return the key of a given col;row coordinate  func key(coords : Vector2) -> int:  	if not is_on_map(coords): return -1 @@ -468,3 +498,28 @@ func shortest_path(piece : Piece, from : Tile,  to : Tile, tiles : Array) -> int  			t = t.parent  		tiles.push_front(from)  	return tiles.size() + +func range_of_influence(piece : Piece, from : Tile, category : int, tiles : Array) -> int: +	tiles.clear() +	var max_range : int = piece.max_range_of_fire(category, from) +	if not is_on_map(from.coords): return 0 +	var tmp : Array = [] +	search_count += 1 +	from.search_count = search_count +	stack.push_back(from) +	while(not stack.empty()): +		var src : Tile = stack.pop_back() +		# warning-ignore:return_value_discarded +		build_adjacents(src.coords) +		for dst in adjacents: +			if not dst.on_board: continue +			if dst.search_count == search_count: continue +			dst.search_count = search_count +			var d : int = int(distance(from.coords, dst.coords, false)) +			if d > max_range: continue +			if line_of_sight(from.coords, dst.coords, tmp).x != -1: continue +			var o : int = distant_orientation(from, dst) +			dst.f = piece.volume_of_fire(category, d, from, o, dst, distant_opposite(o)) +			stack.push_back(dst) +			tiles.append(dst) +	return tiles.size() @@ -22,3 +22,14 @@ func move_cost(src : Tile, dst : Tile, orientation : int) -> int:  func at_least_one_tile(dst : Tile) -> bool:  	print("Piece#at_least_one_tile() must be overriden in a subclass")  	return true + +# the maximum range of fire with a given category of weapon +func max_range_of_fire(category : int, from : Tile) -> int: +	print("Piece#max_range_of_fire() must be overriden in a subclass") +	return 0 + +# the projected volume of fire with a given category of weapon at a given distance, +# out of a given Tile with a given orientation, into a given Tile with a given orientation +func volume_of_fire(category : int, distance : int, src : Tile, src_o : int, dst : Tile, dst_o : int) -> int: +	print("Piece#volume_of_fire() must be overriden in a subclass") +	return -1 # out of range @@ -35,6 +35,21 @@ func block_los(from : Tile, to : Tile, d : float, dt : float) -> bool:  	print("Tile#block_los() must be overriden in a subclass")  	return false +# range value modifier when firing out of this tile with a given category of weapon +func range_modifier(category : int) -> int: +	print("Tile#range_modifier() must be overriden in a subclass") +	return 0 + +# attack value modifier when firing out of this tile with a given category of weapon with a given orientation +func attack_modifier(category : int, orientation : int) -> int: +	print("Tile#attack_modifier() must be overriden in a subclass") +	return 0 + +# defense value provided by this tile against a given category of weapon incoming from a given orientation +func defense_value(category : int, orientation : int) -> int: +	print("Tile#defense_value() must be overriden in a subclass") +	return 0 +  func enable_overlay(i :int, v : bool) -> void:  	get_child(i).visible = v  	if v: visible = true @@ -11,3 +11,15 @@ func road_march_bonus() -> int:  func move_cost(src : Tile, dst : Tile, orientation : int) -> int:  	return (1 if (src.has_road(orientation) and dst.type != 3) else dst.cost()) + +func max_range_of_fire(category : int, from : Tile) -> int: +	return 6 + from.range_modifier(category) + +func volume_of_fire(category : int, distance : int, src : Tile, src_o : int, dst : Tile, dst_o : int) -> int: +	var fp : int = 10 +	if distance > 6: return -1 +	elif distance > 4: fp = 4 +	elif distance > 2: fp = 7 +	fp -= src.attack_modifier(category, src_o) +	fp -= dst.defense_value(category, dst_o) +	return fp | 
