diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..824e801 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.import +*~* +*\#* \ No newline at end of file diff --git a/src/.gitattributes b/src/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/src/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/src/Data/action.gd b/src/Data/action.gd new file mode 100644 index 0000000..e85fb56 --- /dev/null +++ b/src/Data/action.gd @@ -0,0 +1,17 @@ +extends Node +class_name Action + +var action_name: String +var damages: int +var rune = null + +func _init(rune, action_name, damages): + self.rune = rune + self.action_name = action_name + self.damages = damages + +func _ready(): + pass + +func _process(delta): + pass diff --git a/src/Data/actor.gd b/src/Data/actor.gd new file mode 100644 index 0000000..567c50e --- /dev/null +++ b/src/Data/actor.gd @@ -0,0 +1,87 @@ +extends Node +class_name Actor + +var runes: Array = [] +var actor_name: String + +func _init(actor_name: String): + self.actor_name = actor_name + self.give_rune('hp') + self.give_rune('ap') + self.give_rune('atk') + self.give_rune('def') + self.give_rune('ini') + +func hurt(damages): + var target_rune = null + + for rune in self.runes: + if rune.state.hp > 0 and (target_rune == null or rune.state.hp < target_rune.state.hp): + target_rune = rune + + if target_rune: + target_rune.state.hp -= damages + +func give_rune(rune_name: String): + var lib = RuneLib.new() + var rune = lib.find(rune_name) + rune.actor = self + runes.push_back(rune) + +func get_rune(slot_id: int): + if slot_id < self.runes.size(): + return self.runes[slot_id] + return null + +func get_rune_by_name(rune_name: String): + for rune in self.runes: + if rune.rune_name == rune_name: + return rune + return null + +func get_rune_by_slot(slot: int): + for rune in self.runes: + if rune.slot == slot: + return rune + return null + +func get_actor_name() -> String: + return self.actor_name + +func get_hp() -> int: + var res = 0 + for rune in self.runes: + if rune.has_slot(): + res += rune.state.hp + return res + +func get_ap() -> int: + var res = 0 + for rune in self.runes: + if rune.has_slot(): + res = max(res, rune.state.ap) + return res + +func get_atk() -> int: + var res = 0 + for rune in self.runes: + if rune.has_slot(): + res += rune.state.atk + return res + +func get_def() -> int: + var res = 0 + for rune in self.runes: + if rune.has_slot(): + res += rune.state.def + return res + +func get_ini() -> int: + var res = 0 + for rune in self.runes: + if rune.has_slot(): + res = max(res, rune.state.ini) + return res + +func is_dead(): + return self.get_hp() <= 0 diff --git a/src/Data/rune.gd b/src/Data/rune.gd new file mode 100644 index 0000000..9600c98 --- /dev/null +++ b/src/Data/rune.gd @@ -0,0 +1,30 @@ +extends Node +class_name Rune + +var rune_name: String +var state: State +var slot: int +const NO_SLOT = -1 +var actions: Array = [] +var actor: Actor + +func _init(actor, rune_name, state: State): + self.actor = actor + self.rune_name = rune_name + self.state = state + self.slot = NO_SLOT + +func set_slot(slot: int): + self.slot = slot + +func has_slot() -> bool: + return self.slot != NO_SLOT + +func add_action(action): + self.actions.push_back(action) + +func has_action(action): + for a in self.actions: + if a == action: + return true + return false diff --git a/src/Data/runelib.gd b/src/Data/runelib.gd new file mode 100644 index 0000000..84f14f2 --- /dev/null +++ b/src/Data/runelib.gd @@ -0,0 +1,23 @@ +extends Node +class_name RuneLib + +var all_runes: Dictionary = {} + +func _init(): + var hp = add_rune('hp', State.new(100, 0, 0, 0, 0)) + hp.add_action(Action.new(hp, 'Frappe I', 4)) + hp.add_action(Action.new(hp, 'Frappe II', 40)) + hp.add_action(Action.new(hp, 'Frappe III', 75)) + add_rune('ap', State.new(0, 1, 0, 0, 0)) + add_rune('atk', State.new(0, 0, 2, 0, 0)) + add_rune('def', State.new(0, 0, 0, 1, 0)) + add_rune('ini', State.new(0, 0, 0, 0, 1)) + +func add_rune(rune_name: String, state: State): + self.all_runes[rune_name] = Rune.new(null, rune_name, state) + return self.all_runes[rune_name] + +func find(rune_name: String) -> Rune: + assert(rune_name in self.all_runes.keys()) + return self.all_runes[rune_name] + diff --git a/src/Data/slots.gd b/src/Data/slots.gd new file mode 100644 index 0000000..1e29e6f --- /dev/null +++ b/src/Data/slots.gd @@ -0,0 +1,4 @@ +extends Node +class_name Slots + +var runes: Array = [] diff --git a/src/Data/state.gd b/src/Data/state.gd new file mode 100644 index 0000000..c096966 --- /dev/null +++ b/src/Data/state.gd @@ -0,0 +1,15 @@ +extends Node +class_name State + +var hp: int +var ap: int +var atk: int +var def: int +var ini: int + +func _init(_hp, _ap, _atk, _def, _ini): + self.hp = _hp + self.ap = _ap + self.atk = _atk + self.def = _def + self.ini = _ini diff --git a/src/EnemyUI/enemy_ui.gd b/src/EnemyUI/enemy_ui.gd new file mode 100644 index 0000000..18842cc --- /dev/null +++ b/src/EnemyUI/enemy_ui.gd @@ -0,0 +1,16 @@ +extends Control + +var actor: Actor + +func _ready(): + self.actor = Gactor.current_enemy + get_node('%RuneSlots').actor = self.actor + Gai.rune_slots = get_node('%RuneSlots') + +func _process(delta): + get_node('%ActorName').text = str(self.actor.get_actor_name()) + get_node('%HP').text = str(self.actor.get_hp()) + get_node('%AP').text = str(self.actor.get_ap()) + get_node('%ATK').text = str(self.actor.get_atk()) + get_node('%DEF').text = str(self.actor.get_def()) + get_node('%INI').text = str(self.actor.get_ini()) diff --git a/src/EnemyUI/enemy_ui.tscn b/src/EnemyUI/enemy_ui.tscn new file mode 100644 index 0000000..bd4c81a --- /dev/null +++ b/src/EnemyUI/enemy_ui.tscn @@ -0,0 +1,80 @@ +[gd_scene load_steps=3 format=3 uid="uid://bmug7u0mpwj7a"] + +[ext_resource type="Script" path="res://EnemyUI/enemy_ui.gd" id="1_1sdxq"] +[ext_resource type="PackedScene" uid="uid://crngpd2jeu4sx" path="res://RuneSlots/rune_slots.tscn" id="2_le6ii"] + +[node name="EnemyUI" type="Control"] +layout_mode = 3 +anchor_left = 0.5 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_1sdxq") + +[node name="Panel" type="Panel" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="ActorName" type="Label" parent="Panel/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="HUD" type="HBoxContainer" parent="Panel/VBoxContainer"] +layout_mode = 2 + +[node name="HP_LABEL" type="Label" parent="Panel/VBoxContainer/HUD"] +layout_mode = 2 +text = "HP:" + +[node name="HP" type="Label" parent="Panel/VBoxContainer/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="AP_LABEL" type="Label" parent="Panel/VBoxContainer/HUD"] +layout_mode = 2 +text = "AP:" + +[node name="AP" type="Label" parent="Panel/VBoxContainer/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="ATK_LABEL" type="Label" parent="Panel/VBoxContainer/HUD"] +layout_mode = 2 +text = "ATK:" + +[node name="ATK" type="Label" parent="Panel/VBoxContainer/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="DEF_LABEL" type="Label" parent="Panel/VBoxContainer/HUD"] +layout_mode = 2 +text = "DEF:" + +[node name="DEF" type="Label" parent="Panel/VBoxContainer/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="INI_LABEL" type="Label" parent="Panel/VBoxContainer/HUD"] +layout_mode = 2 +text = "INI:" + +[node name="INI" type="Label" parent="Panel/VBoxContainer/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="RuneSlots" parent="Panel/VBoxContainer" instance=ExtResource("2_le6ii")] +unique_name_in_owner = true +layout_mode = 2 diff --git a/src/Global/gactor.gd b/src/Global/gactor.gd new file mode 100644 index 0000000..e8ba168 --- /dev/null +++ b/src/Global/gactor.gd @@ -0,0 +1,16 @@ +extends Node + +var player: Actor +var current_enemy: Actor + +func _ready(): + self.player = Actor.new('Player') + self.current_enemy = Actor.new('Jason') + +func _process(delta): + pass + +func opponent(actor): + if actor == self.player: + return self.current_enemy + return self.player diff --git a/src/Global/gai.gd b/src/Global/gai.gd new file mode 100644 index 0000000..bc6b5d0 --- /dev/null +++ b/src/Global/gai.gd @@ -0,0 +1,38 @@ +extends Node + +var actor: Actor +var rune_slots + +func _process(delta): + if Gturn.current_turn == Gturn.TURN.AI: + if Gturn.current_phase == Gturn.PHASE.RUNES: + self.place_runes() + Gturn.next_phase() + elif Gturn.current_phase == Gturn.PHASE.ACTIONS: + self.select_actions() + Gturn.next_phase() + + +func can_place_rune_in_slot(slot): + for rune in self.actor.runes: + if rune.slot == slot: + return false + return true + +func place_runes(): + randomize() + for rune in self.actor.runes: + if not rune.has_slot(): + while true: + var i = floor(randf_range(0, 5)) + if can_place_rune_in_slot(i): + self.rune_slots.select_rune(rune, i) + return + +func select_actions(): + for rune in self.actor.runes: + if rune.has_slot() and rune.actions.size() > 0: + var action = rune.actions[0] + Gturn.add_action(action) + return + diff --git a/src/Global/gturn.gd b/src/Global/gturn.gd new file mode 100644 index 0000000..04ed170 --- /dev/null +++ b/src/Global/gturn.gd @@ -0,0 +1,63 @@ +extends Node + +enum TURN { + PLAYER, + AI +} + +enum PHASE { + RUNES, + ACTIONS, + RESOLUTION +} + +var PHASE_NAMES = ['READY', 'ATTACK', 'RESOLUTION'] + +var current_turn = TURN.PLAYER +var current_phase = PHASE.RUNES +var current_actions = [] +var phases = [PHASE.RUNES, PHASE.ACTIONS, PHASE.RESOLUTION] +var phase_idx = 0 + +func _ready(): + pass + +func _process(delta): + pass + + +func next_phase(): + if self.current_phase == PHASE.RUNES and self.current_turn == TURN.PLAYER: + self.current_turn = TURN.AI + elif self.current_phase == PHASE.RUNES and self.current_turn == TURN.AI: + self.current_turn = TURN.PLAYER + self.current_phase = PHASE.ACTIONS + elif self.current_phase == PHASE.ACTIONS and self.current_turn == TURN.PLAYER: + self.current_turn = TURN.AI + elif self.current_phase == PHASE.ACTIONS and self.current_turn == TURN.AI: + self.current_turn = TURN.PLAYER + self.current_phase = PHASE.RUNES + self.resolve() + +func add_action(action): + self.current_actions.push_back(action) + +func rune_already_played(rune): + for action in self.current_actions: + if rune.has_action(action): + return true + return false + +func compare_per_ini(lhs, rhs): + return lhs.rune.actor.get_ini() > rhs.rune.actor.get_ini() + +func resolve(): + self.current_actions.sort_custom(self.compare_per_ini) + for action in self.current_actions: + Gactor.opponent(action.rune.actor).hurt(action.damages) + self.current_actions = [] + if Gactor.player.is_dead(): + print('OPPONENT WON') + elif Gactor.current_enemy.is_dead(): + print('PLAYER WON') + diff --git a/src/PlayerUI/player_ui.gd b/src/PlayerUI/player_ui.gd new file mode 100644 index 0000000..fe2ba2a --- /dev/null +++ b/src/PlayerUI/player_ui.gd @@ -0,0 +1,21 @@ +extends Control + +var actor: Actor + +func _ready(): + self.actor = Gactor.player + get_node('%RuneSlots').actor = self.actor + +func _process(delta): + get_node('%ActorName').text = str(self.actor.get_actor_name()) + get_node('%HP').text = str(self.actor.get_hp()) + get_node('%AP').text = str(self.actor.get_ap()) + get_node('%ATK').text = str(self.actor.get_atk()) + get_node('%DEF').text = str(self.actor.get_def()) + get_node('%INI').text = str(self.actor.get_ini()) + get_node('%NextButton').visible = Gturn.current_phase != Gturn.PHASE.RESOLUTION \ + and Gturn.current_turn == Gturn.TURN.PLAYER + get_node('%NextButton').text = Gturn.PHASE_NAMES[Gturn.current_phase] + +func _on_next_button_pressed(): + Gturn.next_phase() diff --git a/src/PlayerUI/player_ui.tscn b/src/PlayerUI/player_ui.tscn new file mode 100644 index 0000000..00f41d2 --- /dev/null +++ b/src/PlayerUI/player_ui.tscn @@ -0,0 +1,91 @@ +[gd_scene load_steps=3 format=3 uid="uid://cscojpnoqu33p"] + +[ext_resource type="Script" path="res://PlayerUI/player_ui.gd" id="1_dik5c"] +[ext_resource type="PackedScene" uid="uid://crngpd2jeu4sx" path="res://RuneSlots/rune_slots.tscn" id="2_6t500"] + +[node name="PlayerUI" type="Control"] +layout_mode = 3 +anchor_right = 0.5 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_dik5c") + +[node name="ActorPanel" type="Panel" parent="."] +unique_name_in_owner = true +clip_contents = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="ActorLayout" type="VBoxContainer" parent="ActorPanel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 2 +alignment = 1 + +[node name="ActorName" type="Label" parent="ActorPanel/ActorLayout"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="HUD" type="HBoxContainer" parent="ActorPanel/ActorLayout"] +layout_mode = 2 +size_flags_vertical = 0 + +[node name="HP_LABEL" type="Label" parent="ActorPanel/ActorLayout/HUD"] +layout_mode = 2 +text = "HP:" + +[node name="HP" type="Label" parent="ActorPanel/ActorLayout/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="AP_LABEL" type="Label" parent="ActorPanel/ActorLayout/HUD"] +layout_mode = 2 +text = "AP:" + +[node name="AP" type="Label" parent="ActorPanel/ActorLayout/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="ATK_LABEL" type="Label" parent="ActorPanel/ActorLayout/HUD"] +layout_mode = 2 +text = "ATK:" + +[node name="ATK" type="Label" parent="ActorPanel/ActorLayout/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="DEF_LABEL" type="Label" parent="ActorPanel/ActorLayout/HUD"] +layout_mode = 2 +text = "DEF:" + +[node name="DEF" type="Label" parent="ActorPanel/ActorLayout/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="INI_LABEL" type="Label" parent="ActorPanel/ActorLayout/HUD"] +layout_mode = 2 +text = "INI:" + +[node name="INI" type="Label" parent="ActorPanel/ActorLayout/HUD"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="RuneSlots" parent="ActorPanel/ActorLayout" instance=ExtResource("2_6t500")] +unique_name_in_owner = true +layout_mode = 2 + +[node name="NextButton" type="Button" parent="ActorPanel/ActorLayout"] +unique_name_in_owner = true +layout_mode = 2 +text = "NEXT" + +[connection signal="pressed" from="ActorPanel/ActorLayout/NextButton" to="." method="_on_next_button_pressed"] diff --git a/src/RuneActions/rune_actions.gd b/src/RuneActions/rune_actions.gd new file mode 100644 index 0000000..158744f --- /dev/null +++ b/src/RuneActions/rune_actions.gd @@ -0,0 +1,25 @@ +extends Control + +var rune = null + +# Called when the node enters the scene tree for the first time. +func _ready(): + var items = get_node('%Items') + + for action in self.rune.actions: + items.add_item(action.action_name) + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + +func _on_button_pressed(): + var items = get_node('%Items') + for item in items.get_selected_items(): + var action_name = items.get_item_text(item) + for action in self.rune.actions: + if action.action_name == action_name: + Gturn.add_action(action) + + get_tree().paused = false + queue_free() diff --git a/src/RuneActions/rune_actions.tscn b/src/RuneActions/rune_actions.tscn new file mode 100644 index 0000000..8b34e9c --- /dev/null +++ b/src/RuneActions/rune_actions.tscn @@ -0,0 +1,44 @@ +[gd_scene load_steps=2 format=3 uid="uid://y7flxg84p7e7"] + +[ext_resource type="Script" path="res://RuneActions/rune_actions.gd" id="1_6vnp1"] + +[node name="RuneActions" type="Control"] +process_mode = 2 +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_6vnp1") + +[node name="Panel" type="Panel" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Label" type="Label" parent="Panel/VBoxContainer"] +layout_mode = 2 +text = "ACTIONS" + +[node name="Items" type="ItemList" parent="Panel/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Button" type="Button" parent="Panel/VBoxContainer"] +layout_mode = 2 +text = "SELECT" + +[connection signal="pressed" from="Panel/VBoxContainer/Button" to="." method="_on_button_pressed"] diff --git a/src/RuneList/rune_list.gd b/src/RuneList/rune_list.gd new file mode 100644 index 0000000..3d694a2 --- /dev/null +++ b/src/RuneList/rune_list.gd @@ -0,0 +1,26 @@ +extends Control + +var actor: Actor = null +signal rune_selected + +func _ready(): + var items = get_node('%Items') + var runes = Gactor.player.runes + for rune in runes: + if not rune.has_slot(): + items.add_item(rune.rune_name) + +func _process(delta): + pass + +func _on_button_pressed(): + var items : ItemList = get_node('%Items') + var selected = items.get_selected_items() + for s in selected: + var item_name = items.get_item_text(s) + assert(self.actor) + var rune = self.actor.get_rune_by_name(item_name) + emit_signal("rune_selected", rune) + + get_tree().paused = false + queue_free() diff --git a/src/RuneList/rune_list.tscn b/src/RuneList/rune_list.tscn new file mode 100644 index 0000000..a8a6406 --- /dev/null +++ b/src/RuneList/rune_list.tscn @@ -0,0 +1,52 @@ +[gd_scene load_steps=2 format=3 uid="uid://bn0q76fi3711l"] + +[ext_resource type="Script" path="res://RuneList/rune_list.gd" id="1_klufn"] + +[node name="RuneList" type="Control"] +process_mode = 2 +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_klufn") + +[node name="Panel" type="Panel" parent="."] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -176.0 +offset_top = -195.0 +offset_right = 176.0 +offset_bottom = 195.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="Panel"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Label" type="Label" parent="Panel/VBoxContainer"] +layout_mode = 2 +text = "RUNES" +horizontal_alignment = 1 + +[node name="Items" type="ItemList" parent="Panel/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +auto_height = true + +[node name="Button" type="Button" parent="Panel/VBoxContainer"] +layout_mode = 2 +text = "TAKE" + +[connection signal="pressed" from="Panel/VBoxContainer/Button" to="." method="_on_button_pressed"] diff --git a/src/RuneSlots/SlotsPanel.gd b/src/RuneSlots/SlotsPanel.gd new file mode 100644 index 0000000..34e55b9 --- /dev/null +++ b/src/RuneSlots/SlotsPanel.gd @@ -0,0 +1,54 @@ +extends Panel + +var A: Vector2 +var B: Vector2 +var C: Vector2 +var D: Vector2 +var E: Vector2 +var rad: int +var center: Vector2 + +func _ready(): + pass + +func _process(delta): + var view = get_rect() + self.center = Vector2(view.size / 2) + self.rad = view.size.x/6 + var v_offset = PI/5 + var h_offset = PI/16 + self.A = get_point(-PI/2 + v_offset) + self.B = get_point(h_offset) + self.C = get_point(PI/2) + self.D = get_point(PI - h_offset) + self.E = get_point(-PI/2 - v_offset) + queue_redraw() + +func get_point(angle): + return self.center + Vector2(cos(angle), sin(angle)) * self.rad + +func _draw(): + draw_circle(self.center, self.rad, Color.RED) + + var slot_rad = rad/8 + var slot_color = Color.RED + draw_circle(self.A, slot_rad, slot_color) + draw_circle(self.B, slot_rad, slot_color) + draw_circle(self.C, slot_rad, slot_color) + draw_circle(self.D, slot_rad, slot_color) + draw_circle(self.E, slot_rad, slot_color) + + var color = Color.BLACK + var width = 8 + draw_line(self.A, self.C, color, width) + draw_line(self.A, self.D, color, width) + draw_line(self.B, self.E, color, width) + draw_line(self.B, self.D, color, width) + draw_line(self.C, self.E, color, width) + draw_line(self.C, self.A, color, width) + draw_line(self.D, self.A, color, width) + draw_line(self.D, self.B, color, width) + + + + diff --git a/src/RuneSlots/rune_slots.gd b/src/RuneSlots/rune_slots.gd new file mode 100644 index 0000000..77dbd89 --- /dev/null +++ b/src/RuneSlots/rune_slots.gd @@ -0,0 +1,137 @@ +extends Control + +var A: Vector2 +var B: Vector2 +var C: Vector2 +var D: Vector2 +var E: Vector2 +var rad: int +var slot_rad: int +var center: Vector2 +var rune_list: PackedScene +var mouse: Vector2 +var current_point: Vector2 +var points: Array +var actor: Actor + +func _ready(): + self.rune_list = preload("res://RuneList/rune_list.tscn") + +func _process(delta): + # positions + # ========= + var view = get_rect() + self.center = Vector2(view.size / 2) + self.rad = view.size.x/3 + self.slot_rad = rad/6 + + var v_offset = PI/5 + var h_offset = PI/16 + self.A = get_point(-PI/2 + v_offset) + self.B = get_point(h_offset) + self.C = get_point(PI/2) + self.D = get_point(PI - h_offset) + self.E = get_point(-PI/2 - v_offset) + self.points = [self.A, self.B, self.C, self.D, self.E] + queue_redraw() + + # events + # ====== + self.mouse = get_local_mouse_position() + + # phase runes + # =========== + if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) \ + and Gturn.current_phase == Gturn.PHASE.RUNES \ + and Gturn.current_turn == Gturn.TURN.PLAYER \ + and self.actor == Gactor.player: + var point = self.get_current_point() + var rune = self.point_to_rune(point) + + if point and not rune: + var lst = self.rune_list.instantiate() + lst.actor = self.actor + lst.rune_selected.connect(self._on_rune_selected.bind(point)) + add_child(lst) + get_tree().paused = true + + if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT) \ + and Gturn.current_phase == Gturn.PHASE.RUNES \ + and Gturn.current_turn == Gturn.TURN.PLAYER \ + and self.actor == Gactor.player: + var point = self.get_current_point() + if point: + var rune = self.point_to_rune(point) + if rune: + rune.set_slot(rune.NO_SLOT) + + # phase actions + if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) \ + and Gturn.current_phase == Gturn.PHASE.ACTIONS \ + and Gturn.current_turn == Gturn.TURN.PLAYER \ + and self.actor == Gactor.player: + var actions = preload("res://RuneActions/rune_actions.tscn").instantiate() + var point = get_current_point() + var rune = point_to_rune(point) + if rune and not Gturn.rune_already_played(rune) \ + and rune.actions.size() > 0: + actions.rune = rune + add_child(actions) + get_tree().paused = true + +func _on_rune_selected(rune, point): + self.select_rune(rune, self.point_to_slot(point)) + Gturn.next_phase() + +func select_rune(rune, slot): + var res = rune.has_slot() + if res: + return false + rune.set_slot(slot) + return true + +func get_point(angle): + return self.center + Vector2(cos(angle), sin(angle)) * self.rad + +func get_current_point(): + for point in self.points: + var dist = self.mouse.distance_squared_to(point) <= slot_rad * slot_rad + if dist: + return point + return null + + +func point_to_slot(point: Vector2): + var slot = self.points.find(point) + return slot + +func point_to_rune(point): + if point == null: + return null + var slot = self.point_to_slot(point) + return self.actor.get_rune_by_slot(slot) + +func _draw(): + draw_circle(self.center, self.rad, Color.DARK_RED) + + for point in self.points: + var slot_color = Color.DARK_RED + var slot = self.point_to_slot(point) + if self.actor.get_rune_by_slot(slot) != null: + slot_color = Color.BLACK + elif self.get_current_point() == point \ + and self.actor == Gactor.player: + slot_color = Color.RED + + draw_circle(point, slot_rad, slot_color) + + var color = Color.RED + var width = 1 + draw_line(self.A, self.C, color, width) + draw_line(self.A, self.D, color, width) + draw_line(self.B, self.E, color, width) + draw_line(self.B, self.D, color, width) + draw_line(self.C, self.E, color, width) + draw_line(self.C, self.A, color, width) + draw_line(self.D, self.A, color, width) + draw_line(self.D, self.B, color, width) diff --git a/src/RuneSlots/rune_slots.tscn b/src/RuneSlots/rune_slots.tscn new file mode 100644 index 0000000..e677e1a --- /dev/null +++ b/src/RuneSlots/rune_slots.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=2 format=3 uid="uid://crngpd2jeu4sx"] + +[ext_resource type="Script" path="res://RuneSlots/rune_slots.gd" id="1_qeglk"] + +[node name="RuneSlots" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1_qeglk") diff --git a/src/Sandbox/sandbox.gd b/src/Sandbox/sandbox.gd new file mode 100644 index 0000000..037526d --- /dev/null +++ b/src/Sandbox/sandbox.gd @@ -0,0 +1,7 @@ +extends Control + +func _ready(): + Gai.actor = get_node('%EnemyUI').actor + +func _process(delta): + pass diff --git a/src/Sandbox/sandbox.tscn b/src/Sandbox/sandbox.tscn new file mode 100644 index 0000000..2143b82 --- /dev/null +++ b/src/Sandbox/sandbox.tscn @@ -0,0 +1,35 @@ +[gd_scene load_steps=4 format=3 uid="uid://bk8owxoblg1aq"] + +[ext_resource type="Script" path="res://Sandbox/sandbox.gd" id="1_e7uy8"] +[ext_resource type="PackedScene" uid="uid://cscojpnoqu33p" path="res://PlayerUI/player_ui.tscn" id="1_eowhn"] +[ext_resource type="PackedScene" uid="uid://bmug7u0mpwj7a" path="res://EnemyUI/enemy_ui.tscn" id="3_0501f"] + +[node name="Sandbox" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1_e7uy8") +metadata/_edit_use_anchors_ = true + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="PlayerUI" parent="HBoxContainer" instance=ExtResource("1_eowhn")] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="EnemyUI" parent="HBoxContainer" instance=ExtResource("3_0501f")] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 diff --git a/src/icon.svg b/src/icon.svg new file mode 100644 index 0000000..b370ceb --- /dev/null +++ b/src/icon.svg @@ -0,0 +1 @@ + diff --git a/src/project.godot b/src/project.godot new file mode 100644 index 0000000..3924124 --- /dev/null +++ b/src/project.godot @@ -0,0 +1,27 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Ludum Dare 55" +run/main_scene="res://Sandbox/sandbox.tscn" +config/features=PackedStringArray("4.2", "GL Compatibility") +config/icon="res://icon.svg" + +[autoload] + +Gactor="*res://Global/gactor.gd" +Gturn="*res://Global/gturn.gd" +Gai="*res://Global/gai.gd" + +[rendering] + +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility"