Shop and Map Ui integrations
This commit is contained in:
parent
d778f08a95
commit
dfcd0dcc63
11 changed files with 484 additions and 87 deletions
|
|
@ -46,6 +46,7 @@ var is_initialized: bool = false
|
||||||
@onready var turnIndicator: ColorRect = $TurnIndicator
|
@onready var turnIndicator: ColorRect = $TurnIndicator
|
||||||
@onready var p1String: RichTextLabel = $Player1Points
|
@onready var p1String: RichTextLabel = $Player1Points
|
||||||
@onready var p2String: RichTextLabel = $Player2Points
|
@onready var p2String: RichTextLabel = $Player2Points
|
||||||
|
@onready var gold: int = 1000
|
||||||
@onready var deckManager: DeckManager
|
@onready var deckManager: DeckManager
|
||||||
@onready var tileManager: TileManager
|
@onready var tileManager: TileManager
|
||||||
@onready var cameraController: CameraController
|
@onready var cameraController: CameraController
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,7 @@
|
||||||
extends RefCounted
|
extends RefCounted
|
||||||
class_name ChessMapGenerator
|
class_name ChessMapGenerator
|
||||||
|
|
||||||
# Room type enum
|
|
||||||
enum RoomType {
|
|
||||||
STARTING,
|
|
||||||
NORMAL,
|
|
||||||
BOSS,
|
|
||||||
FINAL,
|
|
||||||
SHOP,
|
|
||||||
EVENT
|
|
||||||
}
|
|
||||||
|
|
||||||
var min_levels = 10
|
var min_levels = 10
|
||||||
var max_levels = 20
|
var max_levels = 20
|
||||||
|
|
@ -42,19 +34,25 @@ func generate_map():
|
||||||
|
|
||||||
var start_node = {
|
var start_node = {
|
||||||
"id": _get_next_id(),
|
"id": _get_next_id(),
|
||||||
"type": RoomType.STARTING,
|
"type": Utils.RoomType.STARTING,
|
||||||
"level": 0,
|
"level": 0,
|
||||||
"position": Vector2(3, 0),
|
"position": Vector2(3, 0),
|
||||||
|
"metadata": {
|
||||||
|
"is_escape": false,
|
||||||
|
},
|
||||||
"elo": starting_elo
|
"elo": starting_elo
|
||||||
}
|
}
|
||||||
nodes.append(start_node)
|
nodes.append(start_node)
|
||||||
|
|
||||||
# Create final boss node (always at position 3, highest level)
|
# Create final boss node
|
||||||
var final_node = {
|
var final_node = {
|
||||||
"id": _get_next_id(),
|
"id": _get_next_id(),
|
||||||
"type": RoomType.FINAL,
|
"type": Utils.RoomType.FINAL,
|
||||||
"level": num_levels - 1,
|
"level": num_levels - 1,
|
||||||
"position": Vector2(3, num_levels - 1),
|
"position": Vector2(3, num_levels - 1),
|
||||||
|
"metadata": {
|
||||||
|
"is_escape": true,
|
||||||
|
},
|
||||||
"elo": final_elo
|
"elo": final_elo
|
||||||
}
|
}
|
||||||
nodes.append(final_node)
|
nodes.append(final_node)
|
||||||
|
|
@ -79,8 +77,10 @@ func generate_map():
|
||||||
"type": node_type,
|
"type": node_type,
|
||||||
"level": level,
|
"level": level,
|
||||||
"position": Vector2(available_positions[i], level),
|
"position": Vector2(available_positions[i], level),
|
||||||
"elo": level_elo
|
"elo": level_elo,
|
||||||
|
"metadata": {}
|
||||||
}
|
}
|
||||||
|
node = generate_node_data(node)
|
||||||
nodes.append(node)
|
nodes.append(node)
|
||||||
level_nodes.append(node)
|
level_nodes.append(node)
|
||||||
|
|
||||||
|
|
@ -162,7 +162,19 @@ func generate_map():
|
||||||
|
|
||||||
if from_valid and to_valid:
|
if from_valid and to_valid:
|
||||||
valid_connections.append(conn)
|
valid_connections.append(conn)
|
||||||
|
var index = 0
|
||||||
|
for valid_node in valid_nodes:
|
||||||
|
var isLeaf = true;
|
||||||
|
for connection in valid_connections:
|
||||||
|
# if theres outgoing connection we arent at a dead end
|
||||||
|
# dont change final node colour
|
||||||
|
if connection.from == valid_node.id || valid_node.id == 1:
|
||||||
|
isLeaf = false
|
||||||
|
break;
|
||||||
|
valid_node.metadata.is_escape = isLeaf
|
||||||
|
valid_nodes[index] = valid_node;
|
||||||
|
index += 1
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"nodes": valid_nodes,
|
"nodes": valid_nodes,
|
||||||
"connections": valid_connections,
|
"connections": valid_connections,
|
||||||
|
|
@ -180,13 +192,13 @@ func _get_random_room_type(level, total_levels):
|
||||||
|
|
||||||
var roll = _rng.randf()
|
var roll = _rng.randf()
|
||||||
if roll < boss_chance:
|
if roll < boss_chance:
|
||||||
return RoomType.BOSS
|
return Utils.RoomType.BOSS
|
||||||
elif roll < boss_chance + shop_chance:
|
elif roll < boss_chance + shop_chance:
|
||||||
return RoomType.SHOP
|
return Utils.RoomType.SHOP
|
||||||
elif roll < boss_chance + shop_chance + event_chance:
|
elif roll < boss_chance + shop_chance + event_chance:
|
||||||
return RoomType.EVENT
|
return Utils.RoomType.EVENT
|
||||||
else:
|
else:
|
||||||
return RoomType.NORMAL
|
return Utils.RoomType.NORMAL
|
||||||
|
|
||||||
func _is_node_connected_to(node_id, connections):
|
func _is_node_connected_to(node_id, connections):
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
|
|
@ -217,3 +229,78 @@ func get_weighted_node_count(min_count, max_count):
|
||||||
node_count = max_count
|
node_count = max_count
|
||||||
|
|
||||||
return node_count
|
return node_count
|
||||||
|
|
||||||
|
func generate_node_data(node):
|
||||||
|
var data = {
|
||||||
|
"id": node.id,
|
||||||
|
"type": node.type,
|
||||||
|
"level": node.level,
|
||||||
|
"position": node.position,
|
||||||
|
"elo": node.elo,
|
||||||
|
"metadata": node.metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
match data.type:
|
||||||
|
Utils.RoomType.STARTING:
|
||||||
|
data.metadata = generate_starting_data(data, )
|
||||||
|
Utils.RoomType.NORMAL:
|
||||||
|
data.metadata = generate_chess_data(data)
|
||||||
|
Utils.RoomType.BOSS:
|
||||||
|
data.metadata = {}
|
||||||
|
Utils.RoomType.FINAL:
|
||||||
|
data.metadata = { "is_escape": true}
|
||||||
|
Utils.RoomType.SHOP:
|
||||||
|
data.metadata = generate_shop_data(data)
|
||||||
|
Utils.RoomType.EVENT:
|
||||||
|
data.metadata = {}
|
||||||
|
_:
|
||||||
|
data.metadata = {}
|
||||||
|
return data
|
||||||
|
|
||||||
|
func generate_shop_data(node):
|
||||||
|
return {
|
||||||
|
"is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false,
|
||||||
|
"gold": 1000,
|
||||||
|
"cards": generate_shop_cards(),
|
||||||
|
}
|
||||||
|
func generate_shop_cards():
|
||||||
|
var shop_cards = []
|
||||||
|
|
||||||
|
var all_cards = []
|
||||||
|
var card_classes = [
|
||||||
|
HopscotchCard,
|
||||||
|
FieryCapeCard,
|
||||||
|
FieryTrailCard,
|
||||||
|
ExplosiveBootsCard,
|
||||||
|
DoubleTimeCard,
|
||||||
|
DrunkDrivingCard,
|
||||||
|
SupernovaCard
|
||||||
|
]
|
||||||
|
|
||||||
|
for card_class in card_classes:
|
||||||
|
var card = card_class.new()
|
||||||
|
all_cards.append(card)
|
||||||
|
|
||||||
|
all_cards.shuffle()
|
||||||
|
|
||||||
|
var num_shop_cards = min(randi_range(5, 7), all_cards.size())
|
||||||
|
|
||||||
|
for i in range(num_shop_cards):
|
||||||
|
shop_cards.append(all_cards[i % card_classes.size()])
|
||||||
|
|
||||||
|
return shop_cards
|
||||||
|
|
||||||
|
|
||||||
|
func generate_starting_data(node):
|
||||||
|
return {
|
||||||
|
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||||
|
"elo": node.elo,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func generate_chess_data(node):
|
||||||
|
return {
|
||||||
|
"is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false,
|
||||||
|
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||||
|
"elo": node.elo,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,6 @@ signal node_selected(node_data)
|
||||||
|
|
||||||
const MapGenerator = preload("res://Systems/Game/Map/MapGenerator.gd")
|
const MapGenerator = preload("res://Systems/Game/Map/MapGenerator.gd")
|
||||||
# Room type constants
|
# Room type constants
|
||||||
enum RoomType {
|
|
||||||
STARTING,
|
|
||||||
NORMAL,
|
|
||||||
BOSS,
|
|
||||||
FINAL,
|
|
||||||
SHOP,
|
|
||||||
EVENT
|
|
||||||
}
|
|
||||||
|
|
||||||
# Node config
|
# Node config
|
||||||
const NODE_SIZE = Vector2(60, 60)
|
const NODE_SIZE = Vector2(60, 60)
|
||||||
|
|
@ -28,21 +20,21 @@ const NODE_COLOR = Color(0.1, 0.1, 0.1, 0.5)
|
||||||
const NODE_LEAF = Color(0.2, 0.6, 0.2)
|
const NODE_LEAF = Color(0.2, 0.6, 0.2)
|
||||||
# Node symbols and colors
|
# Node symbols and colors
|
||||||
const NODE_SYMBOLS = {
|
const NODE_SYMBOLS = {
|
||||||
RoomType.STARTING: "O", # Circle
|
Utils.RoomType.STARTING: "O", # Circle
|
||||||
RoomType.NORMAL: "■", # Square
|
Utils.RoomType.NORMAL: "■", # Square
|
||||||
RoomType.BOSS: "★", # Star
|
Utils.RoomType.BOSS: "★", # Star
|
||||||
RoomType.FINAL: "✱", # Burst
|
Utils.RoomType.FINAL: "✱", # Burst
|
||||||
RoomType.SHOP: "₵", # Star
|
Utils.RoomType.SHOP: "₵", # Star
|
||||||
RoomType.EVENT: "?" # Burst
|
Utils.RoomType.EVENT: "?" # Burst
|
||||||
}
|
}
|
||||||
|
|
||||||
const NODE_COLORS = {
|
const NODE_COLORS = {
|
||||||
RoomType.STARTING: Color(1, 1, 1), # White
|
Utils.RoomType.STARTING: Color(1, 1, 1), # White
|
||||||
RoomType.NORMAL: Color(0.2, 0.2, 0.2), # Dark gray
|
Utils.RoomType.NORMAL: Color(0.2, 0.2, 0.2), # Dark gray
|
||||||
RoomType.BOSS: Color(0.9, 0.2, 0.2), # Red
|
Utils.RoomType.BOSS: Color(0.9, 0.2, 0.2), # Red
|
||||||
RoomType.FINAL: Color(0.9, 0.9, 0.2), # Yellow
|
Utils.RoomType.FINAL: Color(0.9, 0.9, 0.2), # Yellow
|
||||||
RoomType.SHOP: Color(0.2, 0.7, 0.9), # Yellow
|
Utils.RoomType.SHOP: Color(0.2, 0.7, 0.9), # Yellow
|
||||||
RoomType.EVENT: Color(0.8, 0.4, 0.9) # Yellow
|
Utils.RoomType.EVENT: Color(0.8, 0.4, 0.9) # Yellow
|
||||||
}
|
}
|
||||||
|
|
||||||
var map_nodes = []
|
var map_nodes = []
|
||||||
|
|
@ -57,6 +49,8 @@ const SCROLL_PADDING_BOTTOM = 80
|
||||||
const SCROLL_PADDING_LEFT = 60
|
const SCROLL_PADDING_LEFT = 60
|
||||||
const SCROLL_PADDING_RIGHT = 100
|
const SCROLL_PADDING_RIGHT = 100
|
||||||
|
|
||||||
|
var node_popup_scene = preload("res://node_map_popup.tscn")
|
||||||
|
var selected_node_panel: NodePopup = null
|
||||||
|
|
||||||
@onready var map_container = $MapScrollContainer/MapContainer
|
@onready var map_container = $MapScrollContainer/MapContainer
|
||||||
@onready var back_button = $BackButton
|
@onready var back_button = $BackButton
|
||||||
|
|
@ -72,17 +66,23 @@ func _ready():
|
||||||
create_legend()
|
create_legend()
|
||||||
generate_map()
|
generate_map()
|
||||||
display_map()
|
display_map()
|
||||||
|
selected_node_panel = node_popup_scene.instantiate()
|
||||||
|
selected_node_panel.visible = false
|
||||||
|
add_child(selected_node_panel)
|
||||||
|
|
||||||
|
if selected_node_panel:
|
||||||
|
selected_node_panel.pressed.connect(on_node_panel_pressed)
|
||||||
|
|
||||||
func create_legend():
|
func create_legend():
|
||||||
# Create legend for room types
|
# Create legend for room types
|
||||||
var legend_items = [
|
var legend_items = [
|
||||||
{"type": RoomType.BOSS, "text": "Boss"},
|
{"type": Utils.RoomType.BOSS, "text": "Boss"},
|
||||||
{"type": RoomType.STARTING, "text": "Starting Room"},
|
{"type": Utils.RoomType.STARTING, "text": "Starting Room"},
|
||||||
{"type": RoomType.FINAL, "text": "Final Boss"},
|
{"type": Utils.RoomType.FINAL, "text": "Final Boss"},
|
||||||
{"type": RoomType.NORMAL, "text": "Normal Room"},
|
{"type": Utils.RoomType.NORMAL, "text": "Normal Room"},
|
||||||
{"type": RoomType.SHOP, "text": "Shop"},
|
{"type": Utils.RoomType.SHOP, "text": "Shop"},
|
||||||
{"type": RoomType.EVENT, "text": "Event"},
|
{"type": Utils.RoomType.EVENT, "text": "Event"},
|
||||||
{"type": RoomType.NORMAL, "text": "Escape Room"}
|
{"type": Utils.RoomType.NORMAL, "text": "Escape Room"}
|
||||||
]
|
]
|
||||||
|
|
||||||
for item in legend_items:
|
for item in legend_items:
|
||||||
|
|
@ -112,7 +112,7 @@ func generate_map():
|
||||||
# Create starting node
|
# Create starting node
|
||||||
# var start_node = {
|
# var start_node = {
|
||||||
# "id": 0,
|
# "id": 0,
|
||||||
# "type": RoomType.STARTING,
|
# "type": Utils.RoomType.STARTING,
|
||||||
# "level": 0,
|
# "level": 0,
|
||||||
# "position": Vector2(3, 4) # Column, Row
|
# "position": Vector2(3, 4) # Column, Row
|
||||||
# }
|
# }
|
||||||
|
|
@ -122,7 +122,7 @@ func generate_map():
|
||||||
# # Create final boss node
|
# # Create final boss node
|
||||||
# var final_node = {
|
# var final_node = {
|
||||||
# "id": 1,
|
# "id": 1,
|
||||||
# "type": RoomType.FINAL,
|
# "type": Utils.RoomType.FINAL,
|
||||||
# "level": levels - 1,
|
# "level": levels - 1,
|
||||||
# "position": Vector2(3, 0) # Column, Row
|
# "position": Vector2(3, 0) # Column, Row
|
||||||
# }
|
# }
|
||||||
|
|
@ -133,7 +133,8 @@ func generate_map():
|
||||||
node_data.type,
|
node_data.type,
|
||||||
node_data.level,
|
node_data.level,
|
||||||
node_data.position,
|
node_data.position,
|
||||||
node_data.elo
|
node_data.elo,
|
||||||
|
node_data.metadata
|
||||||
)
|
)
|
||||||
|
|
||||||
# Store elo rating if needed
|
# Store elo rating if needed
|
||||||
|
|
@ -148,13 +149,14 @@ func generate_map():
|
||||||
add_connection(connection.from, connection.to)
|
add_connection(connection.from, connection.to)
|
||||||
|
|
||||||
|
|
||||||
func add_node(id, type, level, position, elo):
|
func add_node(id, type, level, position, elo, metadata):
|
||||||
map_nodes.append({
|
map_nodes.append({
|
||||||
"id": id,
|
"id": id,
|
||||||
"type": type,
|
"type": type,
|
||||||
"level": level,
|
"level": level,
|
||||||
"position": position,
|
"position": position,
|
||||||
"elo": elo
|
"elo": elo,
|
||||||
|
"metadata": metadata,
|
||||||
})
|
})
|
||||||
|
|
||||||
func add_connection(from_id, to_id):
|
func add_connection(from_id, to_id):
|
||||||
|
|
@ -278,7 +280,6 @@ func draw_node(node_data):
|
||||||
|
|
||||||
# Connect signal
|
# Connect signal
|
||||||
button.pressed.connect(func(): _on_node_pressed(node_data))
|
button.pressed.connect(func(): _on_node_pressed(node_data))
|
||||||
|
|
||||||
# Add to map
|
# Add to map
|
||||||
map_container.add_child(button)
|
map_container.add_child(button)
|
||||||
node_buttons[node_data.id] = button
|
node_buttons[node_data.id] = button
|
||||||
|
|
@ -287,6 +288,23 @@ func draw_node(node_data):
|
||||||
if current_node and node_data.id == current_node.id:
|
if current_node and node_data.id == current_node.id:
|
||||||
highlight_current_node(button)
|
highlight_current_node(button)
|
||||||
|
|
||||||
|
func on_node_panel_pressed(id):
|
||||||
|
# print("on_node_panel_pressed ", id )
|
||||||
|
if id != null:
|
||||||
|
|
||||||
|
current_node = null
|
||||||
|
for node in map_nodes:
|
||||||
|
if node.id == id:
|
||||||
|
current_node = node
|
||||||
|
break
|
||||||
|
|
||||||
|
traversed_node(current_node)
|
||||||
|
# Refresh display to update highlights
|
||||||
|
display_map()
|
||||||
|
|
||||||
|
# Emit signal with selected node data
|
||||||
|
emit_signal("node_selected", current_node)
|
||||||
|
selected_node_panel.visible = false;
|
||||||
func draw_connection(from_node, to_node):
|
func draw_connection(from_node, to_node):
|
||||||
var line = Line2D.new()
|
var line = Line2D.new()
|
||||||
line.width = LINE_WIDTH
|
line.width = LINE_WIDTH
|
||||||
|
|
@ -319,14 +337,22 @@ func highlight_current_node(button):
|
||||||
|
|
||||||
func _on_node_pressed(node_data):
|
func _on_node_pressed(node_data):
|
||||||
if is_node_accessible(node_data) || is_node_path_accessible(node_data):
|
if is_node_accessible(node_data) || is_node_path_accessible(node_data):
|
||||||
# Update current node
|
# Get node type description
|
||||||
current_node = node_data
|
var node_name = get_node_type_name(node_data.type)
|
||||||
traversed_node(node_data)
|
var node_desc = get_node_description(node_data)
|
||||||
# Refresh display to update highlights
|
|
||||||
display_map()
|
|
||||||
|
|
||||||
# Emit signal with selected node data
|
# Position the popup near the clicked node
|
||||||
emit_signal("node_selected", node_data)
|
var button_pos = node_buttons[node_data.id].global_position
|
||||||
|
var popup_pos = button_pos + Vector2(NODE_SIZE.x/2, NODE_SIZE.y/2)
|
||||||
|
selected_node_panel.global_position = popup_pos
|
||||||
|
|
||||||
|
# Set popup data and make it visible
|
||||||
|
selected_node_panel.set_card(node_data.id, node_name, node_desc)
|
||||||
|
if traversed_map.has(node_data.id):
|
||||||
|
selected_node_panel._disable_enter()
|
||||||
|
else:
|
||||||
|
selected_node_panel._enable_enter()
|
||||||
|
selected_node_panel.visible = true
|
||||||
else:
|
else:
|
||||||
print("Node not accessible from current position", node_data)
|
print("Node not accessible from current position", node_data)
|
||||||
|
|
||||||
|
|
@ -335,7 +361,7 @@ func traversed_node(node_data):
|
||||||
|
|
||||||
func is_node_path_accessible(node_data):
|
func is_node_path_accessible(node_data):
|
||||||
if current_node == null:
|
if current_node == null:
|
||||||
return node_data.type == RoomType.STARTING
|
return node_data.type == Utils.RoomType.STARTING
|
||||||
|
|
||||||
# Check if there's a direct connection from current node to the path travelled
|
# Check if there's a direct connection from current node to the path travelled
|
||||||
for id in traversed_map:
|
for id in traversed_map:
|
||||||
|
|
@ -348,7 +374,7 @@ func is_node_path_accessible(node_data):
|
||||||
|
|
||||||
func is_node_accessible(node_data):
|
func is_node_accessible(node_data):
|
||||||
if current_node == null:
|
if current_node == null:
|
||||||
return node_data.type == RoomType.STARTING
|
return node_data.type == Utils.RoomType.STARTING
|
||||||
|
|
||||||
# Check if there's a direct connection from current node to target node
|
# Check if there's a direct connection from current node to target node
|
||||||
for connection in map_connections:
|
for connection in map_connections:
|
||||||
|
|
@ -432,3 +458,54 @@ func quadratic_bezier(p0: Vector2, p1: Vector2, p2: Vector2, t: float) -> Vector
|
||||||
var q1 = p1.lerp(p2, t)
|
var q1 = p1.lerp(p2, t)
|
||||||
|
|
||||||
return q0.lerp(q1, t)
|
return q0.lerp(q1, t)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func get_node_type_name(type):
|
||||||
|
match type:
|
||||||
|
Utils.RoomType.STARTING:
|
||||||
|
return "Starting Room"
|
||||||
|
Utils.RoomType.NORMAL:
|
||||||
|
return "Chess Match"
|
||||||
|
Utils.RoomType.BOSS:
|
||||||
|
return "Boss Battle"
|
||||||
|
Utils.RoomType.FINAL:
|
||||||
|
return "Final Boss"
|
||||||
|
Utils.RoomType.SHOP:
|
||||||
|
return "Card Shop"
|
||||||
|
Utils.RoomType.EVENT:
|
||||||
|
return "Random Event"
|
||||||
|
_:
|
||||||
|
return "Unknown Room"
|
||||||
|
|
||||||
|
|
||||||
|
func get_node_description(node_data):
|
||||||
|
var desc = ""
|
||||||
|
match node_data.type:
|
||||||
|
Utils.RoomType.STARTING:
|
||||||
|
desc = "Begin the dungeon"
|
||||||
|
Utils.RoomType.NORMAL:
|
||||||
|
desc = "A chess match \n\n ELO: " + str(node_data.elo)
|
||||||
|
Utils.RoomType.BOSS:
|
||||||
|
desc = "Maybe add some Boss lore? \n\n ELO: " + str(node_data.elo)
|
||||||
|
Utils.RoomType.FINAL:
|
||||||
|
desc = "BHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHA"
|
||||||
|
Utils.RoomType.SHOP:
|
||||||
|
desc = "Purchase new cards"
|
||||||
|
Utils.RoomType.EVENT:
|
||||||
|
desc = "A random event from pawn zerg to slot machine"
|
||||||
|
_:
|
||||||
|
desc = "An unknown room type."
|
||||||
|
|
||||||
|
# Add additional info if this is a leaf node (dead end)
|
||||||
|
var isLeaf = true
|
||||||
|
for connection in map_connections:
|
||||||
|
if connection.from == node_data.id || node_data.id == 1:
|
||||||
|
isLeaf = false
|
||||||
|
break
|
||||||
|
|
||||||
|
if isLeaf && node_data.type != Utils.RoomType.FINAL:
|
||||||
|
desc += "\n\nWarning: This is an escape node"
|
||||||
|
|
||||||
|
return desc
|
||||||
|
|
|
||||||
132
Systems/Game/Map/NodePopup.gd
Normal file
132
Systems/Game/Map/NodePopup.gd
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
# Add or modify this in your CardVisual.gd script
|
||||||
|
|
||||||
|
extends Control
|
||||||
|
class_name NodePopup
|
||||||
|
|
||||||
|
signal pressed(id)
|
||||||
|
# Node references
|
||||||
|
@onready var card_container = $CardContainer
|
||||||
|
@onready var name_label = $CardContainer/VBoxContainer/NameLabel
|
||||||
|
@onready var desc_label = $CardContainer/VBoxContainer/DescriptionLabel
|
||||||
|
@onready var enter_btn = $CardContainer/VBoxContainer/HBoxContainer/EnterButton
|
||||||
|
@onready var close_btn = $CardContainer/VBoxContainer/HBoxContainer/CloseButton
|
||||||
|
var node_id = null;
|
||||||
|
var animation_tween
|
||||||
|
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
|
||||||
|
mouse_filter = Control.MOUSE_FILTER_STOP
|
||||||
|
gui_input.connect(_on_gui_input)
|
||||||
|
if card_container:
|
||||||
|
card_container.mouse_filter = Control.MOUSE_FILTER_PASS
|
||||||
|
for child in get_children():
|
||||||
|
if child is Control:
|
||||||
|
child.mouse_filter = Control.MOUSE_FILTER_PASS
|
||||||
|
|
||||||
|
if enter_btn:
|
||||||
|
enter_btn.connect("pressed", Callable(self, "_on_enter_button_pressed"))
|
||||||
|
|
||||||
|
if close_btn:
|
||||||
|
close_btn.connect("pressed", Callable(self, "_on_close_button_pressed"))
|
||||||
|
card_container.visible = false
|
||||||
|
# Setup initial scale for animation
|
||||||
|
card_container.scale = Vector2(0.8, 0.8)
|
||||||
|
set_process_input(true)
|
||||||
|
|
||||||
|
|
||||||
|
func set_card(id:int, name: String, desc: String):
|
||||||
|
if id == null:
|
||||||
|
card_container.visible = false
|
||||||
|
return
|
||||||
|
|
||||||
|
node_id = id
|
||||||
|
card_container.visible = true
|
||||||
|
|
||||||
|
name_label.text = name
|
||||||
|
desc_label.text = desc
|
||||||
|
|
||||||
|
# Animate popup appearance
|
||||||
|
if animation_tween:
|
||||||
|
animation_tween.kill()
|
||||||
|
|
||||||
|
animation_tween = create_tween()
|
||||||
|
animation_tween.tween_property(card_container, "scale", Vector2(1.0, 1.0), 0.2).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
|
||||||
|
|
||||||
|
# Make sure popup is fully visible on screen
|
||||||
|
call_deferred("ensure_on_screen")
|
||||||
|
|
||||||
|
func ensure_on_screen():
|
||||||
|
await get_tree().process_frame
|
||||||
|
# Get viewport size
|
||||||
|
var viewport_size = get_viewport_rect().size
|
||||||
|
# Get popup global position and size
|
||||||
|
var popup_rect = Rect2(global_position, card_container.size)
|
||||||
|
|
||||||
|
# Adjust if off-screen
|
||||||
|
if popup_rect.position.x < 0:
|
||||||
|
global_position.x = 10
|
||||||
|
elif popup_rect.position.x + popup_rect.size.x > viewport_size.x:
|
||||||
|
global_position.x = viewport_size.x - popup_rect.size.x - 10
|
||||||
|
|
||||||
|
if popup_rect.position.y < 0:
|
||||||
|
global_position.y = 10
|
||||||
|
elif popup_rect.position.y + popup_rect.size.y > viewport_size.y:
|
||||||
|
global_position.y = viewport_size.y - popup_rect.size.y - 10
|
||||||
|
|
||||||
|
|
||||||
|
func _on_gui_input(event):
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.tween_property(card_container, "scale", Vector2(1.05, 1.05), 0.1)
|
||||||
|
tween.tween_property(card_container, "scale", Vector2(1.0, 1.0), 0.1)
|
||||||
|
|
||||||
|
# Handle dragging the popup
|
||||||
|
var dragging = false
|
||||||
|
var drag_start_pos = Vector2()
|
||||||
|
|
||||||
|
func _input(event):
|
||||||
|
if not visible or not card_container.visible:
|
||||||
|
return
|
||||||
|
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.button_index == MOUSE_BUTTON_LEFT:
|
||||||
|
if event.pressed:
|
||||||
|
# Check if mouse is over the card container
|
||||||
|
var local_mouse_pos = get_local_mouse_position()
|
||||||
|
if card_container.get_rect().has_point(local_mouse_pos):
|
||||||
|
dragging = true
|
||||||
|
drag_start_pos = local_mouse_pos - card_container.position
|
||||||
|
else:
|
||||||
|
dragging = false
|
||||||
|
|
||||||
|
elif event is InputEventMouseMotion and dragging:
|
||||||
|
card_container.position = get_local_mouse_position() - drag_start_pos
|
||||||
|
func _on_enter_button_pressed():
|
||||||
|
# Add a confirmation animation before closing
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.tween_property(card_container, "scale", Vector2(1.1, 1.1), 0.1)
|
||||||
|
tween.tween_property(card_container, "scale", Vector2(0.8, 0.8), 0.2)
|
||||||
|
tween.tween_callback(func(): _confirm_selection())
|
||||||
|
|
||||||
|
func _disable_enter():
|
||||||
|
enter_btn.disabled = true;
|
||||||
|
func _enable_enter():
|
||||||
|
enter_btn.disabled = false;
|
||||||
|
|
||||||
|
func _confirm_selection():
|
||||||
|
emit_signal("pressed", node_id)
|
||||||
|
card_container.visible = false
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
func _on_close_button_pressed():
|
||||||
|
# Add a closing animation
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.tween_property(card_container, "scale", Vector2(0.8, 0.8), 0.2)
|
||||||
|
tween.tween_callback(func(): _cancel_selection())
|
||||||
|
|
||||||
|
func _cancel_selection():
|
||||||
|
emit_signal("pressed", null)
|
||||||
|
card_container.visible = false
|
||||||
|
visible = false
|
||||||
1
Systems/Game/Map/NodePopup.gd.uid
Normal file
1
Systems/Game/Map/NodePopup.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://tsgxcwb1u8uc
|
||||||
|
|
@ -21,8 +21,9 @@ signal card_purchased(card, price)
|
||||||
@onready var mapScreen = get_node("/root/Board/MapScreen")
|
@onready var mapScreen = get_node("/root/Board/MapScreen")
|
||||||
@onready var stateMachine = get_node("/root/Board/StateMachine")
|
@onready var stateMachine = get_node("/root/Board/StateMachine")
|
||||||
@onready var shopScreen = get_node("/root/Board/ShopScreen")
|
@onready var shopScreen = get_node("/root/Board/ShopScreen")
|
||||||
|
# back up if game isn't loaded yet?
|
||||||
var player_gold = 1000
|
var player_gold = 10
|
||||||
|
var back_to_map = false
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
# Connect menu option signals
|
# Connect menu option signals
|
||||||
|
|
@ -121,26 +122,42 @@ func _on_shop_open_requested(options):
|
||||||
|
|
||||||
if options == null:
|
if options == null:
|
||||||
options = {}
|
options = {}
|
||||||
options["gold"] = player_gold
|
|
||||||
|
var game = get_node_or_null("/root/Board") as ChessGame
|
||||||
|
|
||||||
|
if "gold" in options:
|
||||||
|
if game and "gold" in game:
|
||||||
|
options["gold"] = game.gold
|
||||||
|
else:
|
||||||
|
options["gold"] = player_gold
|
||||||
if shopScreen:
|
if shopScreen:
|
||||||
shopScreen.visible = true
|
shopScreen.visible = true
|
||||||
shopScreen.initialize(options)
|
shopScreen.initialize(options)
|
||||||
emit_signal("shop_open_requested", options)
|
emit_signal("shop_open_requested", options)
|
||||||
|
|
||||||
func _on_shop_back_pressed():
|
func _on_shop_back_pressed():
|
||||||
|
var game = get_node_or_null("/root/Board") as ChessGame
|
||||||
if shopScreen:
|
if shopScreen:
|
||||||
shopScreen.visible = false
|
shopScreen.visible = false
|
||||||
player_gold = shopScreen.player_gold
|
if game and "gold" in game:
|
||||||
|
game.gold = shopScreen.player_gold
|
||||||
|
else:
|
||||||
|
player_gold = shopScreen.player_gold
|
||||||
|
|
||||||
# Show game menu again
|
# Show game menu again
|
||||||
if gameMenuScreen:
|
if not back_to_map and gameMenuScreen:
|
||||||
gameMenuScreen.visible = true
|
gameMenuScreen.visible = true
|
||||||
|
if back_to_map:
|
||||||
|
mapScreen.visible = true
|
||||||
# Emit signal that shop was closed
|
# Emit signal that shop was closed
|
||||||
emit_signal("shop_closed")
|
emit_signal("shop_closed")
|
||||||
|
|
||||||
func _on_shop_card_purchased(card, price):
|
func _on_shop_card_purchased(card, price):
|
||||||
player_gold -= price
|
var game = get_node_or_null("/root/Board") as ChessGame
|
||||||
|
if game and "gold" in game:
|
||||||
|
game.gold -= price
|
||||||
|
else:
|
||||||
|
player_gold -= price
|
||||||
# Forward the signal
|
# Forward the signal
|
||||||
emit_signal("card_purchased", card, price)
|
emit_signal("card_purchased", card, price)
|
||||||
|
|
||||||
|
|
@ -168,7 +185,10 @@ func _on_deckmanager_open_requested(options):
|
||||||
func _on_deck_manager_back_pressed():
|
func _on_deck_manager_back_pressed():
|
||||||
# Return to game menu screen
|
# Return to game menu screen
|
||||||
deckManagerScreen.visible = false
|
deckManagerScreen.visible = false
|
||||||
gameMenuScreen.visible = true
|
if not back_to_map:
|
||||||
|
gameMenuScreen.visible = true
|
||||||
|
else:
|
||||||
|
mapScreen.visible = true
|
||||||
|
|
||||||
|
|
||||||
func _on_map_open_requested(options):
|
func _on_map_open_requested(options):
|
||||||
|
|
@ -190,6 +210,10 @@ func _on_map_back_pressed():
|
||||||
# Map node selection
|
# Map node selection
|
||||||
func _on_map_node_selected(node_data):
|
func _on_map_node_selected(node_data):
|
||||||
print("Selected map node: ", node_data)
|
print("Selected map node: ", node_data)
|
||||||
|
if node_data.type == Utils.RoomType.SHOP:
|
||||||
|
back_to_map = true
|
||||||
|
_on_shop_open_requested(node_data.metadata)
|
||||||
|
|
||||||
# Implement logic for map node selection
|
# Implement logic for map node selection
|
||||||
# For example, start a battle based on the node type
|
# For example, start a battle based on the node type
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,6 @@ func select_card(index):
|
||||||
|
|
||||||
for i in range(card_carousel.get_child_count()):
|
for i in range(card_carousel.get_child_count()):
|
||||||
var card_visual = card_carousel.get_child(i)
|
var card_visual = card_carousel.get_child(i)
|
||||||
print(i ," vi ", visual_index, " Ind ", index, " cp ", cards_per_page)
|
|
||||||
card_visual.set_selected(i == visual_index)
|
card_visual.set_selected(i == visual_index)
|
||||||
|
|
||||||
if card_preview and selected_card:
|
if card_preview and selected_card:
|
||||||
|
|
|
||||||
|
|
@ -56,4 +56,13 @@ static var LIGHT_CELL = Color(0.5, 0.5, 0.5, 1)
|
||||||
static var DARK_CELL = Color(0.2, 0.2, 0.2, 1)
|
static var DARK_CELL = Color(0.2, 0.2, 0.2, 1)
|
||||||
static var GREEN_CELL = Color(0.36, 0.62, 0.43, 1)
|
static var GREEN_CELL = Color(0.36, 0.62, 0.43, 1)
|
||||||
static var WALL_CELL = Color(0.59, 0.29, 0.0, 1) # Brown (#964B00)
|
static var WALL_CELL = Color(0.59, 0.29, 0.0, 1) # Brown (#964B00)
|
||||||
static var DOUBLE_WALL = Color(0.36, 0.17, 0.0, 1) # Dark Brown (#5C2B00)
|
static var DOUBLE_WALL = Color(0.36, 0.17, 0.0, 1) # Dark Brown (#5C2B00)
|
||||||
|
|
||||||
|
enum RoomType {
|
||||||
|
STARTING,
|
||||||
|
NORMAL,
|
||||||
|
BOSS,
|
||||||
|
FINAL,
|
||||||
|
SHOP,
|
||||||
|
EVENT
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -396,6 +396,7 @@ visible = false
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
|
||||||
[node name="ShopScreen" parent="." instance=ExtResource("30_5rfmq")]
|
[node name="ShopScreen" parent="." instance=ExtResource("30_5rfmq")]
|
||||||
|
visible = false
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
|
||||||
[node name="MapContainer" type="Control" parent="ShopScreen"]
|
[node name="MapContainer" type="Control" parent="ShopScreen"]
|
||||||
|
|
|
||||||
83
node_map_popup.tscn
Normal file
83
node_map_popup.tscn
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
[gd_scene load_steps=3 format=3 uid="uid://b6ldneayg8mqq"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://tsgxcwb1u8uc" path="res://Systems/Game/Map/NodePopup.gd" id="1_5o0ng"]
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_mkr1p"]
|
||||||
|
bg_color = Color(0.14902, 0.14902, 0.188235, 1)
|
||||||
|
border_color = Color(1, 0.8, 0, 1)
|
||||||
|
corner_radius_top_left = 10
|
||||||
|
corner_radius_top_right = 10
|
||||||
|
corner_radius_bottom_right = 10
|
||||||
|
corner_radius_bottom_left = 10
|
||||||
|
|
||||||
|
[node name="NodePopup" type="Control"]
|
||||||
|
custom_minimum_size = Vector2(150, 250)
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 0
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
script = ExtResource("1_5o0ng")
|
||||||
|
|
||||||
|
[node name="CardContainer" type="Panel" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_bottom = -50.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
pivot_offset = Vector2(75, 125)
|
||||||
|
theme_override_styles/panel = SubResource("StyleBoxFlat_mkr1p")
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="CardContainer"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = 10.0
|
||||||
|
offset_top = 10.0
|
||||||
|
offset_right = -10.0
|
||||||
|
offset_bottom = -10.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="NameLabel" type="Label" parent="CardContainer/VBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(50, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_font_sizes/font_size = 18
|
||||||
|
text = "Node Name"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
autowrap_mode = 3
|
||||||
|
|
||||||
|
[node name="HSeparator" type="HSeparator" parent="CardContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="DescriptionLabel" type="Label" parent="CardContainer/VBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(50, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_font_sizes/font_size = 11
|
||||||
|
text = "SomeDescription for the selected node and can probalby shrink this text"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
autowrap_mode = 2
|
||||||
|
|
||||||
|
[node name="Spacer" type="Control" parent="CardContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="CardContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="EnterButton" type="Button" parent="CardContainer/VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "Enter"
|
||||||
|
|
||||||
|
[node name="VSeparator" type="VSeparator" parent="CardContainer/VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="CloseButton" type="Button" parent="CardContainer/VBoxContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "Close
|
||||||
|
"
|
||||||
|
|
@ -133,20 +133,3 @@ size_flags_vertical = 4
|
||||||
theme_override_font_sizes/font_size = 18
|
theme_override_font_sizes/font_size = 18
|
||||||
theme_override_styles/normal = SubResource("StyleBoxFlat_jk2fb")
|
theme_override_styles/normal = SubResource("StyleBoxFlat_jk2fb")
|
||||||
text = "BUY (50 gold)"
|
text = "BUY (50 gold)"
|
||||||
|
|
||||||
[node name="BottomBar" type="HBoxContainer" parent="."]
|
|
||||||
visible = false
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 12
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_top = -80.0
|
|
||||||
offset_bottom = -20.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 0
|
|
||||||
alignment = 1
|
|
||||||
|
|
||||||
[node name="Spacer" type="Control" parent="BottomBar"]
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue