From 89723ca94bd21f1ae14592a682e9c0e5c5f04a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Mon, 20 Jul 2020 12:26:48 +0200 Subject: move demo files into subdir demo --- Camera.gd | 36 ------------ Hex.gd | 80 -------------------------- Los.gd | 21 ------- Main.gd | 65 --------------------- Main.tscn | 155 -------------------------------------------------- Map.gd | 174 --------------------------------------------------------- Map.tscn | 4 -- Unit.gd | 25 --------- demo/Camera.gd | 36 ++++++++++++ demo/Hex.gd | 80 ++++++++++++++++++++++++++ demo/Los.gd | 21 +++++++ demo/Main.gd | 65 +++++++++++++++++++++ demo/Main.tscn | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++ demo/Map.gd | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ demo/Map.tscn | 4 ++ demo/Unit.gd | 25 +++++++++ project.godot | 6 +- 17 files changed, 563 insertions(+), 563 deletions(-) delete mode 100644 Camera.gd delete mode 100644 Hex.gd delete mode 100644 Los.gd delete mode 100644 Main.gd delete mode 100644 Main.tscn delete mode 100644 Map.gd delete mode 100644 Map.tscn delete mode 100644 Unit.gd create mode 100644 demo/Camera.gd create mode 100644 demo/Hex.gd create mode 100644 demo/Los.gd create mode 100644 demo/Main.gd create mode 100644 demo/Main.tscn create mode 100644 demo/Map.gd create mode 100644 demo/Map.tscn create mode 100644 demo/Unit.gd diff --git a/Camera.gd b/Camera.gd deleted file mode 100644 index 0dc6074..0000000 --- a/Camera.gd +++ /dev/null @@ -1,36 +0,0 @@ -extends Camera2D - -var margin :Vector2 -var window : Vector2 -var map_center : Vector2 -var texture_size : Vector2 -var zoom_boundaries : Vector2 - -func _ready(): - margin = Vector2(0, 0) - -func configure(w : Vector2, c : Vector2, ts : Vector2) -> void: - window = w - map_center = c - texture_size = ts - var zout : float = max((texture_size.x + margin.x) / window.x, (texture_size.y + margin.y) / window.y) - zoom_boundaries = Vector2(zout - 0.5, zout) - update_camera(0, 0, zoom_boundaries.y) - -func update_camera(x : float, y : float, z : float) -> void: - if z != 0: - zoom.x = clamp(zoom.x + z, zoom_boundaries.x, zoom_boundaries.y) - zoom.y = zoom.x - position.x += x - position.y += y - var delta = texture_size + margin - (window * zoom.x) - if (delta.x <= 0): - position.x = map_center.x - else: - var dx = int(delta.x / 2) - position.x = clamp(position.x, map_center.x - dx, map_center.x + dx) - if (delta.y <= 0): - position.y = map_center.y - else: - var dy = int(delta.y / 2) - position.y = clamp(position.y, map_center.y - dy, map_center.y + dy) diff --git a/Hex.gd b/Hex.gd deleted file mode 100644 index 99bdbd2..0000000 --- a/Hex.gd +++ /dev/null @@ -1,80 +0,0 @@ -#warning-ignore-all:unused_argument -extends Tile - -class_name Hex, "res://godot/Tile.png" - -var type : int = -1 -var roads : int = 0 - -func _ready() -> void: - type = -1 - -func inspect() -> String: - var s : String = 'plain' - if type == 0: s = 'city' - elif type == 1: s = 'wood' - elif type == 2: s = 'mountain' - elif type == 3: s = 'blocked' - return "[%d;%d]\n -> (%d;%d)\n -> %s\ne:%d h:%d c:%d r:%d" % [coords.x, coords.y, position.x, position.y, s, elevation(), height(), cost(), roads] - -func has_road(o : int) -> bool: - return (o & roads) > 0 - -func change() -> void: - type = (type + 2) % 5 - 1 - for i in range(4): - enable_overlay(i + 3, i == type) - -func cost() -> int: - if type == -1: return 1 - elif type == 3: return -1 - return type + 1 - -func height() -> int: - if type == 0: return 2 - elif type == 1: return 1 - elif type == 2: return 0 - return 0 - -func elevation() -> int: - 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: - var h : int = height() + elevation() - if h == 0: return false - var e : int = from.elevation() - if e > h: - if to.elevation() > h: return false - return (h * dt / (e - h)) >= (d - dt) - h -= e - return ((h * d / dt) >= to.elevation() - e) - -func show_los(b) -> void: - if b: enable_overlay((2 if blocked else 1), true) - else: - enable_overlay(1, false) - enable_overlay(2, false) - -func show_move(b) -> void: - enable_overlay(7, b) - -func show_short(b) -> void: - enable_overlay(8, b) - -func show_influence(b) -> void: - var s : Sprite = get_child(0) - s.modulate = Color(f/10.0, 0, 0) - enable_overlay(0, b) diff --git a/Los.gd b/Los.gd deleted file mode 100644 index 324819a..0000000 --- a/Los.gd +++ /dev/null @@ -1,21 +0,0 @@ -extends Node2D - -var p0 : Vector2 -var p1 : Vector2 -var p2 : Vector2 - -func _ready(): - pass - -func _draw() -> void: - if p2.x == -1: - draw_line(p0, p1, Color(0, 255, 0)) - else: - draw_line(p0, p2, Color(0, 255, 0)) - draw_line(p2, p1, Color(255, 0, 0)) - -func setup(v0 :Vector2, v1 : Vector2, v2 : Vector2) -> void: - p0 = v0 - p1 = v1 - p2 = v2 - update() diff --git a/Main.gd b/Main.gd deleted file mode 100644 index 42b52a9..0000000 --- a/Main.gd +++ /dev/null @@ -1,65 +0,0 @@ -#warning-ignore-all:return_value_discarded -extends Node2D - -var moved : int = 0 -var drag_map : bool = false - -onready var UI : Control = $CanvasLayer/HBOX/UI -onready var Map : Sprite = $CanvasLayer/HBOX/ViewportContainer/Viewport/Map -onready var Camera : Camera2D = $CanvasLayer/HBOX/ViewportContainer/Viewport/Camera - -func _ready(): - UI.get_node("rotate").connect("pressed", self, "on_rotate") - UI.get_node("zin").connect("pressed", self, "on_zoom", [true]) - UI.get_node("zout").connect("pressed", self, "on_zoom", [false]) - UI.get_node("LOS").connect("pressed", self, "on_toggle") - UI.get_node("Move").connect("pressed", self, "on_toggle") - UI.get_node("Influence").connect("pressed", self, "on_toggle") - Map.connect("hex_touched", self, "on_hex_touched") - $CanvasLayer/HBOX/ViewportContainer.connect("resized", self, "on_viewport_resized") - on_toggle() - yield(get_tree().create_timer(.2), 'timeout') - on_viewport_resized() - UI.get_node("OSInfo").text = "screen\n%s\ndpi %d" % [OS.get_screen_size(), OS.get_screen_dpi()] - -func on_viewport_resized() -> void: - Camera.configure($CanvasLayer/HBOX/ViewportContainer/Viewport.size, Map.center(), Map.texture_size()) - -func on_rotate() -> void: - Map.rotate_map() - on_viewport_resized() - -func on_zoom(b : bool) -> void: - Camera.update_camera(0, 0, -0.05 if b else 0.05) - -func on_toggle() -> void: - Map.set_mode(UI.get_node("LOS").pressed, UI.get_node("Move").pressed, UI.get_node("Influence").pressed) - -func on_hex_touched(pos : Vector2, hex : Hex, key : int) -> void: - var s : String = ("offmap" if key == -1 else hex.inspect()) - UI.get_node("Info").set_text("\n(%d;%d)\n -> %s\n -> %d" % [int(pos.x), int(pos.y), s, key]) - -func _unhandled_input(event : InputEvent) -> void: - if event is InputEventMouseMotion: - if drag_map: - var dv : Vector2 = event.relative * Camera.zoom - Camera.update_camera(-dv.x, -dv.y, 0) - moved += 1 - else: - Map.on_mouse_move() - elif event is InputEventMouseButton: - if event.button_index == 1: - if moved < 5: - drag_map = Map.on_click(event.pressed) - else: - drag_map = false - moved = 0 - elif event.button_index == 3: - drag_map = event.pressed - elif event.button_index == 4: - on_zoom(true) - elif event.button_index == 5: - on_zoom(false) - elif event is InputEventKey: - if event.scancode == KEY_ESCAPE: - get_tree().quit() diff --git a/Main.tscn b/Main.tscn deleted file mode 100644 index 27a5ce9..0000000 --- a/Main.tscn +++ /dev/null @@ -1,155 +0,0 @@ -[gd_scene load_steps=10 format=2] - -[ext_resource path="res://Camera.gd" type="Script" id=1] -[ext_resource path="res://Map.gd" type="Script" id=2] -[ext_resource path="res://Main.gd" type="Script" id=3] -[ext_resource path="res://Los.gd" type="Script" id=4] -[ext_resource path="res://assets/Anke.otf" type="DynamicFontData" id=5] -[ext_resource path="res://assets/target.png" type="Texture" id=6] -[ext_resource path="res://assets/tank.png" type="Texture" id=7] - -[sub_resource type="DynamicFont" id=1] -size = 35 -font_data = ExtResource( 5 ) - -[sub_resource type="Theme" id=2] -default_font = SubResource( 1 ) - -[node name="Main" type="Node2D"] -script = ExtResource( 3 ) - -[node name="CanvasLayer" type="CanvasLayer" parent="."] - -[node name="HBOX" type="HBoxContainer" parent="CanvasLayer"] -anchor_right = 1.0 -anchor_bottom = 1.0 -mouse_filter = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="ViewportContainer" type="ViewportContainer" parent="CanvasLayer/HBOX"] -margin_right = 1666.0 -margin_bottom = 1080.0 -rect_min_size = Vector2( 100, 100 ) -mouse_filter = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -stretch = true -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Viewport" type="Viewport" parent="CanvasLayer/HBOX/ViewportContainer"] -size = Vector2( 1666, 1080 ) -handle_input_locally = false -render_target_update_mode = 3 - -[node name="Map" type="Sprite" parent="CanvasLayer/HBOX/ViewportContainer/Viewport"] -script = ExtResource( 2 ) - -[node name="Hexes" type="Node" parent="CanvasLayer/HBOX/ViewportContainer/Viewport/Map"] - -[node name="Target" type="Sprite" parent="CanvasLayer/HBOX/ViewportContainer/Viewport/Map"] -z_index = 1 -texture = ExtResource( 6 ) - -[node name="Tank" type="Sprite" parent="CanvasLayer/HBOX/ViewportContainer/Viewport/Map"] -z_index = 1 -texture = ExtResource( 7 ) - -[node name="Los" type="Node2D" parent="CanvasLayer/HBOX/ViewportContainer/Viewport/Map"] -script = ExtResource( 4 ) - -[node name="Camera" type="Camera2D" parent="CanvasLayer/HBOX/ViewportContainer/Viewport"] -current = true -script = ExtResource( 1 ) - -[node name="UI" type="VBoxContainer" parent="CanvasLayer/HBOX"] -margin_left = 1670.0 -margin_right = 1920.0 -margin_bottom = 1080.0 -rect_min_size = Vector2( 250, 0 ) -theme = SubResource( 2 ) -custom_constants/separation = 30 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="rotate" type="Button" parent="CanvasLayer/HBOX/UI"] -margin_right = 250.0 -margin_bottom = 100.0 -rect_min_size = Vector2( 0, 100 ) -size_flags_horizontal = 3 -text = "Rotate" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="zin" type="Button" parent="CanvasLayer/HBOX/UI"] -margin_top = 130.0 -margin_right = 250.0 -margin_bottom = 230.0 -rect_min_size = Vector2( 0, 100 ) -size_flags_horizontal = 3 -text = "Z IN" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="zout" type="Button" parent="CanvasLayer/HBOX/UI"] -margin_top = 260.0 -margin_right = 250.0 -margin_bottom = 360.0 -rect_min_size = Vector2( 0, 100 ) -size_flags_horizontal = 3 -text = "Z OUT" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="LOS" type="CheckBox" parent="CanvasLayer/HBOX/UI"] -margin_top = 390.0 -margin_right = 250.0 -margin_bottom = 434.0 -pressed = true -text = "LOS" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Move" type="CheckBox" parent="CanvasLayer/HBOX/UI"] -margin_top = 464.0 -margin_right = 250.0 -margin_bottom = 508.0 -text = "Move" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Influence" type="CheckBox" parent="CanvasLayer/HBOX/UI"] -margin_top = 538.0 -margin_right = 250.0 -margin_bottom = 582.0 -text = "Influence" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Info" type="Label" parent="CanvasLayer/HBOX/UI"] -margin_top = 612.0 -margin_right = 250.0 -margin_bottom = 648.0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="OSInfo" type="Label" parent="CanvasLayer/HBOX/UI"] -margin_top = 678.0 -margin_right = 250.0 -margin_bottom = 714.0 -__meta__ = { -"_edit_use_anchors_": false -} diff --git a/Map.gd b/Map.gd deleted file mode 100644 index 81c5c36..0000000 --- a/Map.gd +++ /dev/null @@ -1,174 +0,0 @@ -extends Sprite - -signal hex_touched(pos, hex, key) - -const MAPH : String = "res://assets/map-h.png" -const MAPV : String = "res://assets/map-v.png" -const BLOCK : String = "res://assets/block.png" -const BLACK : String = "res://assets/black.png" -const MOVE : String = "res://assets/move.png" -const SHORT : String = "res://assets/short.png" -const RED : String = "res://assets/red.png" -const GREEN : String = "res://assets/green.png" -const TREE : String = "res://assets/tree.png" -const CITY : String = "res://assets/city.png" -const MOUNT : String = "res://assets/mountain.png" - -var drag : Sprite - -var board : HexBoard -var prev : Vector2 -var hexes : Dictionary -var hex_rotation : int -var p0 : Vector2 -var p1 : Vector2 -var los : Array -var move : Array -var short : Array -var influence : Array -var unit : Unit -var show_los : bool -var show_move : bool -var show_influence : bool - -func _ready(): - drag = null - unit = Unit.new() - board = HexBoard.new() - board.tile_factory_fct = funcref(self, "get_tile") - board.v = false - rotate_map() - -func reset() -> void: - los.clear() - move.clear() - short.clear() - influence.clear() - hexes.clear() - hexes[-1] = Hex.new() # off map - p0 = Vector2(0, 0) - p1 = Vector2(3, 3) - $Tank.position = board.center_of(p0) - $Target.position = board.center_of(p1) - for hex in $Hexes.get_children(): - $Hexes.remove_child(hex) - hex.queue_free() - compute() - -func rotate_map() -> void: - texture = load(MAPH if board.v else MAPV) - configure() - reset() - -func set_mode(l : bool, m : bool, i : bool) -> void: - show_los = l - show_move = m - show_influence = i - compute() - -func configure() -> void: - var v0 : Vector2 = Vector2(50, 100) - if centered: - var ts : Vector2 = texture.get_size() - if board.v: - v0.x -= ts.y / 2 - v0.y -= ts.x / 2 - else: - v0 -= ts / 2 - if board.v: - hex_rotation = 30 - board.configure(10, 4, 100, v0, false) - else: - hex_rotation = 0 - board.configure(10, 7, 100, v0, true) - -func texture_size() -> Vector2: - return texture.get_size() - -func center() -> Vector2: - return Vector2(0, 0) if centered else texture.get_size() / 2 - -func on_mouse_move() -> void: - if drag != null: - drag.position = get_local_mouse_position() - -func on_click(pressed : bool) -> bool: - var pos : Vector2 = get_local_mouse_position() - var coords : Vector2 = board.to_map(pos) - if pressed: - notify(pos, coords) - prev = coords - if board.to_map($Tank.position) == coords: - drag = $Tank - elif board.to_map($Target.position) == coords: - drag = $Target - else: - return true - else: - if drag: - if board.is_on_map(coords): - drag.position = board.center_of(coords) - if drag == $Tank: p0 = coords - else: p1 = coords - notify(pos, coords) - compute() - else: - drag.position = board.center_of(prev) - drag = null - else: - if coords == prev and board.is_on_map(coords): - change_tile(coords, pos) - return false - -func change_tile(coords : Vector2, pos : Vector2) -> void: - var hex : Hex = board.get_tile(coords) - hex.change() - notify(pos, coords) - compute() - -func get_tile(coords : Vector2, k : int) -> Tile: - if hexes.has(k): return hexes[k] - var hex : Hex = Hex.new() - hex.roads = get_road(k) - hex.rotation_degrees = hex_rotation - hex.configure(board.center_of(coords), coords, [RED, GREEN, BLACK, CITY, TREE, MOUNT, BLOCK, MOVE, SHORT]) - hexes[k] = hex - $Hexes.add_child(hex) - return hex - -func get_road(k : int) -> int: - if not board.v: return 0 - var v : int = 0 - v += (HexBoard.Orientation.E if k in [19,20,21,23,24,42,43,44,45,46,47] else 0) - v += (HexBoard.Orientation.W if k in [19,20,21,22,24,25,43,44,45,46,47] else 0) - v += (HexBoard.Orientation.SE if k in [22,32,42,52,62] else 0) - v += (HexBoard.Orientation.NW if k in [32,42,52,62] else 0) - v += (HexBoard.Orientation.NE if k in [7,16,25,32] else 0) - v += (HexBoard.Orientation.SW if k in [7,16,23] else 0) - return v - -func notify(pos : Vector2, coords : Vector2) -> void: - emit_signal("hex_touched", pos, board.get_tile(coords), (board.key(coords) if board.is_on_map(coords) else -1)) - -func compute() -> void: - $Los.visible = false - for hex in los: hex.show_los(false) - if show_los: - $Los.visible = true - var ct : Vector2 = board.line_of_sight(p0, p1, los) - $Los.setup($Tank.position, $Target.position, ct) - for hex in los: hex.show_los(true) - for hex in move: hex.show_move(false) - for hex in short: hex.show_short(false) - if show_move: - # warning-ignore:return_value_discarded - board.possible_moves(unit, board.get_tile(p0), move) - # warning-ignore:return_value_discarded - board.shortest_path(unit, board.get_tile(p0), board.get_tile(p1), short) - for hex in move: hex.show_move(true) - for i in range(1, short.size() -1): short[i].show_short(true) - for hex in influence: hex.show_influence(false) - if show_influence: - # warning-ignore:return_value_discarded - board.range_of_influence(unit, board.get_tile(p0), 0, influence) - for hex in influence: hex.show_influence(true) diff --git a/Map.tscn b/Map.tscn deleted file mode 100644 index 7ebb23c..0000000 --- a/Map.tscn +++ /dev/null @@ -1,4 +0,0 @@ -[gd_scene format=2] - -[node name="Map" type="Sprite"] -centered = false diff --git a/Unit.gd b/Unit.gd deleted file mode 100644 index 0b67053..0000000 --- a/Unit.gd +++ /dev/null @@ -1,25 +0,0 @@ -#warning-ignore-all:unused_argument -extends Piece - -class_name Unit, "res://godot/Piece.png" - -func get_mp() -> int: - return 2 - -func road_march_bonus() -> int: - return 2 - -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 diff --git a/demo/Camera.gd b/demo/Camera.gd new file mode 100644 index 0000000..0dc6074 --- /dev/null +++ b/demo/Camera.gd @@ -0,0 +1,36 @@ +extends Camera2D + +var margin :Vector2 +var window : Vector2 +var map_center : Vector2 +var texture_size : Vector2 +var zoom_boundaries : Vector2 + +func _ready(): + margin = Vector2(0, 0) + +func configure(w : Vector2, c : Vector2, ts : Vector2) -> void: + window = w + map_center = c + texture_size = ts + var zout : float = max((texture_size.x + margin.x) / window.x, (texture_size.y + margin.y) / window.y) + zoom_boundaries = Vector2(zout - 0.5, zout) + update_camera(0, 0, zoom_boundaries.y) + +func update_camera(x : float, y : float, z : float) -> void: + if z != 0: + zoom.x = clamp(zoom.x + z, zoom_boundaries.x, zoom_boundaries.y) + zoom.y = zoom.x + position.x += x + position.y += y + var delta = texture_size + margin - (window * zoom.x) + if (delta.x <= 0): + position.x = map_center.x + else: + var dx = int(delta.x / 2) + position.x = clamp(position.x, map_center.x - dx, map_center.x + dx) + if (delta.y <= 0): + position.y = map_center.y + else: + var dy = int(delta.y / 2) + position.y = clamp(position.y, map_center.y - dy, map_center.y + dy) diff --git a/demo/Hex.gd b/demo/Hex.gd new file mode 100644 index 0000000..99bdbd2 --- /dev/null +++ b/demo/Hex.gd @@ -0,0 +1,80 @@ +#warning-ignore-all:unused_argument +extends Tile + +class_name Hex, "res://godot/Tile.png" + +var type : int = -1 +var roads : int = 0 + +func _ready() -> void: + type = -1 + +func inspect() -> String: + var s : String = 'plain' + if type == 0: s = 'city' + elif type == 1: s = 'wood' + elif type == 2: s = 'mountain' + elif type == 3: s = 'blocked' + return "[%d;%d]\n -> (%d;%d)\n -> %s\ne:%d h:%d c:%d r:%d" % [coords.x, coords.y, position.x, position.y, s, elevation(), height(), cost(), roads] + +func has_road(o : int) -> bool: + return (o & roads) > 0 + +func change() -> void: + type = (type + 2) % 5 - 1 + for i in range(4): + enable_overlay(i + 3, i == type) + +func cost() -> int: + if type == -1: return 1 + elif type == 3: return -1 + return type + 1 + +func height() -> int: + if type == 0: return 2 + elif type == 1: return 1 + elif type == 2: return 0 + return 0 + +func elevation() -> int: + 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: + var h : int = height() + elevation() + if h == 0: return false + var e : int = from.elevation() + if e > h: + if to.elevation() > h: return false + return (h * dt / (e - h)) >= (d - dt) + h -= e + return ((h * d / dt) >= to.elevation() - e) + +func show_los(b) -> void: + if b: enable_overlay((2 if blocked else 1), true) + else: + enable_overlay(1, false) + enable_overlay(2, false) + +func show_move(b) -> void: + enable_overlay(7, b) + +func show_short(b) -> void: + enable_overlay(8, b) + +func show_influence(b) -> void: + var s : Sprite = get_child(0) + s.modulate = Color(f/10.0, 0, 0) + enable_overlay(0, b) diff --git a/demo/Los.gd b/demo/Los.gd new file mode 100644 index 0000000..324819a --- /dev/null +++ b/demo/Los.gd @@ -0,0 +1,21 @@ +extends Node2D + +var p0 : Vector2 +var p1 : Vector2 +var p2 : Vector2 + +func _ready(): + pass + +func _draw() -> void: + if p2.x == -1: + draw_line(p0, p1, Color(0, 255, 0)) + else: + draw_line(p0, p2, Color(0, 255, 0)) + draw_line(p2, p1, Color(255, 0, 0)) + +func setup(v0 :Vector2, v1 : Vector2, v2 : Vector2) -> void: + p0 = v0 + p1 = v1 + p2 = v2 + update() diff --git a/demo/Main.gd b/demo/Main.gd new file mode 100644 index 0000000..42b52a9 --- /dev/null +++ b/demo/Main.gd @@ -0,0 +1,65 @@ +#warning-ignore-all:return_value_discarded +extends Node2D + +var moved : int = 0 +var drag_map : bool = false + +onready var UI : Control = $CanvasLayer/HBOX/UI +onready var Map : Sprite = $CanvasLayer/HBOX/ViewportContainer/Viewport/Map +onready var Camera : Camera2D = $CanvasLayer/HBOX/ViewportContainer/Viewport/Camera + +func _ready(): + UI.get_node("rotate").connect("pressed", self, "on_rotate") + UI.get_node("zin").connect("pressed", self, "on_zoom", [true]) + UI.get_node("zout").connect("pressed", self, "on_zoom", [false]) + UI.get_node("LOS").connect("pressed", self, "on_toggle") + UI.get_node("Move").connect("pressed", self, "on_toggle") + UI.get_node("Influence").connect("pressed", self, "on_toggle") + Map.connect("hex_touched", self, "on_hex_touched") + $CanvasLayer/HBOX/ViewportContainer.connect("resized", self, "on_viewport_resized") + on_toggle() + yield(get_tree().create_timer(.2), 'timeout') + on_viewport_resized() + UI.get_node("OSInfo").text = "screen\n%s\ndpi %d" % [OS.get_screen_size(), OS.get_screen_dpi()] + +func on_viewport_resized() -> void: + Camera.configure($CanvasLayer/HBOX/ViewportContainer/Viewport.size, Map.center(), Map.texture_size()) + +func on_rotate() -> void: + Map.rotate_map() + on_viewport_resized() + +func on_zoom(b : bool) -> void: + Camera.update_camera(0, 0, -0.05 if b else 0.05) + +func on_toggle() -> void: + Map.set_mode(UI.get_node("LOS").pressed, UI.get_node("Move").pressed, UI.get_node("Influence").pressed) + +func on_hex_touched(pos : Vector2, hex : Hex, key : int) -> void: + var s : String = ("offmap" if key == -1 else hex.inspect()) + UI.get_node("Info").set_text("\n(%d;%d)\n -> %s\n -> %d" % [int(pos.x), int(pos.y), s, key]) + +func _unhandled_input(event : InputEvent) -> void: + if event is InputEventMouseMotion: + if drag_map: + var dv : Vector2 = event.relative * Camera.zoom + Camera.update_camera(-dv.x, -dv.y, 0) + moved += 1 + else: + Map.on_mouse_move() + elif event is InputEventMouseButton: + if event.button_index == 1: + if moved < 5: + drag_map = Map.on_click(event.pressed) + else: + drag_map = false + moved = 0 + elif event.button_index == 3: + drag_map = event.pressed + elif event.button_index == 4: + on_zoom(true) + elif event.button_index == 5: + on_zoom(false) + elif event is InputEventKey: + if event.scancode == KEY_ESCAPE: + get_tree().quit() diff --git a/demo/Main.tscn b/demo/Main.tscn new file mode 100644 index 0000000..6fa7f31 --- /dev/null +++ b/demo/Main.tscn @@ -0,0 +1,155 @@ +[gd_scene load_steps=10 format=2] + +[ext_resource path="res://demo/Camera.gd" type="Script" id=1] +[ext_resource path="res://assets/Anke.otf" type="DynamicFontData" id=2] +[ext_resource path="res://assets/target.png" type="Texture" id=3] +[ext_resource path="res://demo/Map.gd" type="Script" id=4] +[ext_resource path="res://demo/Los.gd" type="Script" id=5] +[ext_resource path="res://assets/tank.png" type="Texture" id=6] +[ext_resource path="res://demo/Main.gd" type="Script" id=7] + +[sub_resource type="DynamicFont" id=1] +size = 35 +font_data = ExtResource( 2 ) + +[sub_resource type="Theme" id=2] +default_font = SubResource( 1 ) + +[node name="Main" type="Node2D"] +script = ExtResource( 7 ) + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="HBOX" type="HBoxContainer" parent="CanvasLayer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="ViewportContainer" type="ViewportContainer" parent="CanvasLayer/HBOX"] +margin_right = 1666.0 +margin_bottom = 1080.0 +rect_min_size = Vector2( 100, 100 ) +mouse_filter = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +stretch = true +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Viewport" type="Viewport" parent="CanvasLayer/HBOX/ViewportContainer"] +size = Vector2( 1666, 1080 ) +handle_input_locally = false +render_target_update_mode = 3 + +[node name="Map" type="Sprite" parent="CanvasLayer/HBOX/ViewportContainer/Viewport"] +script = ExtResource( 4 ) + +[node name="Hexes" type="Node" parent="CanvasLayer/HBOX/ViewportContainer/Viewport/Map"] + +[node name="Target" type="Sprite" parent="CanvasLayer/HBOX/ViewportContainer/Viewport/Map"] +z_index = 1 +texture = ExtResource( 3 ) + +[node name="Tank" type="Sprite" parent="CanvasLayer/HBOX/ViewportContainer/Viewport/Map"] +z_index = 1 +texture = ExtResource( 6 ) + +[node name="Los" type="Node2D" parent="CanvasLayer/HBOX/ViewportContainer/Viewport/Map"] +script = ExtResource( 5 ) + +[node name="Camera" type="Camera2D" parent="CanvasLayer/HBOX/ViewportContainer/Viewport"] +current = true +script = ExtResource( 1 ) + +[node name="UI" type="VBoxContainer" parent="CanvasLayer/HBOX"] +margin_left = 1670.0 +margin_right = 1920.0 +margin_bottom = 1080.0 +rect_min_size = Vector2( 250, 0 ) +theme = SubResource( 2 ) +custom_constants/separation = 30 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="rotate" type="Button" parent="CanvasLayer/HBOX/UI"] +margin_right = 250.0 +margin_bottom = 100.0 +rect_min_size = Vector2( 0, 100 ) +size_flags_horizontal = 3 +text = "Rotate" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="zin" type="Button" parent="CanvasLayer/HBOX/UI"] +margin_top = 130.0 +margin_right = 250.0 +margin_bottom = 230.0 +rect_min_size = Vector2( 0, 100 ) +size_flags_horizontal = 3 +text = "Z IN" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="zout" type="Button" parent="CanvasLayer/HBOX/UI"] +margin_top = 260.0 +margin_right = 250.0 +margin_bottom = 360.0 +rect_min_size = Vector2( 0, 100 ) +size_flags_horizontal = 3 +text = "Z OUT" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="LOS" type="CheckBox" parent="CanvasLayer/HBOX/UI"] +margin_top = 390.0 +margin_right = 250.0 +margin_bottom = 434.0 +pressed = true +text = "LOS" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Move" type="CheckBox" parent="CanvasLayer/HBOX/UI"] +margin_top = 464.0 +margin_right = 250.0 +margin_bottom = 508.0 +text = "Move" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Influence" type="CheckBox" parent="CanvasLayer/HBOX/UI"] +margin_top = 538.0 +margin_right = 250.0 +margin_bottom = 582.0 +text = "Influence" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Info" type="Label" parent="CanvasLayer/HBOX/UI"] +margin_top = 612.0 +margin_right = 250.0 +margin_bottom = 648.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="OSInfo" type="Label" parent="CanvasLayer/HBOX/UI"] +margin_top = 678.0 +margin_right = 250.0 +margin_bottom = 714.0 +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/demo/Map.gd b/demo/Map.gd new file mode 100644 index 0000000..81c5c36 --- /dev/null +++ b/demo/Map.gd @@ -0,0 +1,174 @@ +extends Sprite + +signal hex_touched(pos, hex, key) + +const MAPH : String = "res://assets/map-h.png" +const MAPV : String = "res://assets/map-v.png" +const BLOCK : String = "res://assets/block.png" +const BLACK : String = "res://assets/black.png" +const MOVE : String = "res://assets/move.png" +const SHORT : String = "res://assets/short.png" +const RED : String = "res://assets/red.png" +const GREEN : String = "res://assets/green.png" +const TREE : String = "res://assets/tree.png" +const CITY : String = "res://assets/city.png" +const MOUNT : String = "res://assets/mountain.png" + +var drag : Sprite + +var board : HexBoard +var prev : Vector2 +var hexes : Dictionary +var hex_rotation : int +var p0 : Vector2 +var p1 : Vector2 +var los : Array +var move : Array +var short : Array +var influence : Array +var unit : Unit +var show_los : bool +var show_move : bool +var show_influence : bool + +func _ready(): + drag = null + unit = Unit.new() + board = HexBoard.new() + board.tile_factory_fct = funcref(self, "get_tile") + board.v = false + rotate_map() + +func reset() -> void: + los.clear() + move.clear() + short.clear() + influence.clear() + hexes.clear() + hexes[-1] = Hex.new() # off map + p0 = Vector2(0, 0) + p1 = Vector2(3, 3) + $Tank.position = board.center_of(p0) + $Target.position = board.center_of(p1) + for hex in $Hexes.get_children(): + $Hexes.remove_child(hex) + hex.queue_free() + compute() + +func rotate_map() -> void: + texture = load(MAPH if board.v else MAPV) + configure() + reset() + +func set_mode(l : bool, m : bool, i : bool) -> void: + show_los = l + show_move = m + show_influence = i + compute() + +func configure() -> void: + var v0 : Vector2 = Vector2(50, 100) + if centered: + var ts : Vector2 = texture.get_size() + if board.v: + v0.x -= ts.y / 2 + v0.y -= ts.x / 2 + else: + v0 -= ts / 2 + if board.v: + hex_rotation = 30 + board.configure(10, 4, 100, v0, false) + else: + hex_rotation = 0 + board.configure(10, 7, 100, v0, true) + +func texture_size() -> Vector2: + return texture.get_size() + +func center() -> Vector2: + return Vector2(0, 0) if centered else texture.get_size() / 2 + +func on_mouse_move() -> void: + if drag != null: + drag.position = get_local_mouse_position() + +func on_click(pressed : bool) -> bool: + var pos : Vector2 = get_local_mouse_position() + var coords : Vector2 = board.to_map(pos) + if pressed: + notify(pos, coords) + prev = coords + if board.to_map($Tank.position) == coords: + drag = $Tank + elif board.to_map($Target.position) == coords: + drag = $Target + else: + return true + else: + if drag: + if board.is_on_map(coords): + drag.position = board.center_of(coords) + if drag == $Tank: p0 = coords + else: p1 = coords + notify(pos, coords) + compute() + else: + drag.position = board.center_of(prev) + drag = null + else: + if coords == prev and board.is_on_map(coords): + change_tile(coords, pos) + return false + +func change_tile(coords : Vector2, pos : Vector2) -> void: + var hex : Hex = board.get_tile(coords) + hex.change() + notify(pos, coords) + compute() + +func get_tile(coords : Vector2, k : int) -> Tile: + if hexes.has(k): return hexes[k] + var hex : Hex = Hex.new() + hex.roads = get_road(k) + hex.rotation_degrees = hex_rotation + hex.configure(board.center_of(coords), coords, [RED, GREEN, BLACK, CITY, TREE, MOUNT, BLOCK, MOVE, SHORT]) + hexes[k] = hex + $Hexes.add_child(hex) + return hex + +func get_road(k : int) -> int: + if not board.v: return 0 + var v : int = 0 + v += (HexBoard.Orientation.E if k in [19,20,21,23,24,42,43,44,45,46,47] else 0) + v += (HexBoard.Orientation.W if k in [19,20,21,22,24,25,43,44,45,46,47] else 0) + v += (HexBoard.Orientation.SE if k in [22,32,42,52,62] else 0) + v += (HexBoard.Orientation.NW if k in [32,42,52,62] else 0) + v += (HexBoard.Orientation.NE if k in [7,16,25,32] else 0) + v += (HexBoard.Orientation.SW if k in [7,16,23] else 0) + return v + +func notify(pos : Vector2, coords : Vector2) -> void: + emit_signal("hex_touched", pos, board.get_tile(coords), (board.key(coords) if board.is_on_map(coords) else -1)) + +func compute() -> void: + $Los.visible = false + for hex in los: hex.show_los(false) + if show_los: + $Los.visible = true + var ct : Vector2 = board.line_of_sight(p0, p1, los) + $Los.setup($Tank.position, $Target.position, ct) + for hex in los: hex.show_los(true) + for hex in move: hex.show_move(false) + for hex in short: hex.show_short(false) + if show_move: + # warning-ignore:return_value_discarded + board.possible_moves(unit, board.get_tile(p0), move) + # warning-ignore:return_value_discarded + board.shortest_path(unit, board.get_tile(p0), board.get_tile(p1), short) + for hex in move: hex.show_move(true) + for i in range(1, short.size() -1): short[i].show_short(true) + for hex in influence: hex.show_influence(false) + if show_influence: + # warning-ignore:return_value_discarded + board.range_of_influence(unit, board.get_tile(p0), 0, influence) + for hex in influence: hex.show_influence(true) diff --git a/demo/Map.tscn b/demo/Map.tscn new file mode 100644 index 0000000..7ebb23c --- /dev/null +++ b/demo/Map.tscn @@ -0,0 +1,4 @@ +[gd_scene format=2] + +[node name="Map" type="Sprite"] +centered = false diff --git a/demo/Unit.gd b/demo/Unit.gd new file mode 100644 index 0000000..0b67053 --- /dev/null +++ b/demo/Unit.gd @@ -0,0 +1,25 @@ +#warning-ignore-all:unused_argument +extends Piece + +class_name Unit, "res://godot/Piece.png" + +func get_mp() -> int: + return 2 + +func road_march_bonus() -> int: + return 2 + +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 diff --git a/project.godot b/project.godot index 657540a..7f0176a 100644 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ _global_script_classes=[ { "base": "Tile", "class": "Hex", "language": "GDScript", -"path": "res://Hex.gd" +"path": "res://demo/Hex.gd" }, { "base": "Node", "class": "HexBoard", @@ -32,7 +32,7 @@ _global_script_classes=[ { "base": "Piece", "class": "Unit", "language": "GDScript", -"path": "res://Unit.gd" +"path": "res://demo/Unit.gd" } ] _global_script_class_icons={ "Hex": "res://godot/Tile.png", @@ -45,7 +45,7 @@ _global_script_class_icons={ [application] config/name="hexgrid_demo" -run/main_scene="res://Main.tscn" +run/main_scene="res://demo/Main.tscn" config/icon="res://icon.png" [display] -- cgit v1.1-2-g2b99