stable
Ivory 2025-10-10 03:01:08 -04:00
parent 304419b01a
commit cadc389dce
79 changed files with 1954 additions and 458 deletions

View File

@ -0,0 +1,60 @@
[gd_resource type="Theme" load_steps=11 format=3 uid="uid://dks3mt6h14i2s"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8pucy"]
[sub_resource type="StyleBoxLine" id="StyleBoxLine_8pucy"]
color = Color(0.12156863, 0.22745098, 0.3254902, 1)
thickness = 2
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8pucy"]
bg_color = Color(0.15294118, 0.42352942, 0.6627451, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_v3gly"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ihngy"]
content_margin_left = 10.0
content_margin_top = 10.0
content_margin_right = 10.0
content_margin_bottom = 10.0
bg_color = Color(0.15294118, 0.42352942, 0.6627451, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1l7gl"]
content_margin_left = 12.0
content_margin_right = 12.0
bg_color = Color(0.0414, 0.264653, 0.46, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_jnd74"]
content_margin_left = 12.0
content_margin_right = 12.0
bg_color = Color(0.153647, 0.421958, 0.662925, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uvwpq"]
content_margin_left = 12.0
content_margin_right = 12.0
bg_color = Color(0.153647, 0.421958, 0.662925, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kspi0"]
content_margin_left = 12.0
content_margin_right = 12.0
bg_color = Color(0.0414, 0.264653, 0.46, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ynn0i"]
bg_color = Color(0.0414, 0.264653, 0.46, 1)
[resource]
Button/styles/focus = SubResource("StyleBoxEmpty_8pucy")
HSeparator/styles/separator = SubResource("StyleBoxLine_8pucy")
MarginContainer/constants/margin_bottom = 10
MarginContainer/constants/margin_left = 10
MarginContainer/constants/margin_right = 10
MarginContainer/constants/margin_top = 10
Panel/styles/panel = SubResource("StyleBoxFlat_8pucy")
PanelContainer/styles/panel = SubResource("StyleBoxFlat_v3gly")
TabContainer/constants/side_margin = 0
TabContainer/styles/panel = SubResource("StyleBoxFlat_ihngy")
TabContainer/styles/tab_disabled = SubResource("StyleBoxFlat_1l7gl")
TabContainer/styles/tab_focus = SubResource("StyleBoxFlat_jnd74")
TabContainer/styles/tab_hovered = SubResource("StyleBoxFlat_uvwpq")
TabContainer/styles/tab_selected = SubResource("StyleBoxFlat_jnd74")
TabContainer/styles/tab_unselected = SubResource("StyleBoxFlat_kspi0")
TabContainer/styles/tabbar_background = SubResource("StyleBoxFlat_ynn0i")

View File

@ -0,0 +1,8 @@
[gd_resource type="Gradient" format=3 uid="uid://tinbxo2rfy43"]
[resource]
interpolation_mode = 2
interpolation_color_space = 2
offsets = PackedFloat32Array(0, 0.68480724, 1)
colors = PackedColorArray(0.20874, 0.63, 0.2016, 0.5254902, 0.2054, 0.6535935, 0.79, 1, 1, 1, 1, 1)
metadata/_snap_count = 2

View File

@ -0,0 +1,8 @@
[gd_resource type="Gradient" format=3 uid="uid://cwib7d3acghwy"]
[resource]
interpolation_mode = 1
interpolation_color_space = 2
offsets = PackedFloat32Array(0, 0.7596372, 1)
colors = PackedColorArray(1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1)
metadata/_snap_count = 2

View File

@ -0,0 +1,8 @@
[gd_resource type="Gradient" format=3 uid="uid://dxdol27lvcj8n"]
[resource]
interpolation_mode = 2
interpolation_color_space = 2
offsets = PackedFloat32Array(0, 0.68480724, 1)
colors = PackedColorArray(0.6278897, 0.41815576, 0.8109275, 0.5254902, 0.9236453, 0.41345683, 0.37540042, 1, 1, 1, 1, 1)
metadata/_snap_count = 2

View File

@ -0,0 +1,21 @@
[gd_resource type="Theme" load_steps=3 format=3 uid="uid://s3apw670qymv"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0jf1r"]
bg_color = Color(0, 0, 0, 0.65882355)
border_width_left = 1
border_width_top = 1
border_width_right = 1
border_width_bottom = 1
border_color = Color(1, 1, 1, 0.21176471)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lycib"]
bg_color = Color(1, 1, 1, 0.22352941)
border_width_left = 1
border_width_top = 1
border_width_right = 1
border_width_bottom = 1
border_color = Color(0.8, 0.8, 0.8, 0)
[resource]
ProgressBar/styles/background = SubResource("StyleBoxFlat_0jf1r")
ProgressBar/styles/fill = SubResource("StyleBoxFlat_lycib")

View File

@ -0,0 +1,29 @@
extends Resource
class_name BuildingData
enum RenderStyle {
RandomBuilding,
Full,
Outline,
Triangle,
Circles
}
@export_group("Basic")
@export var tile_name: String
@export var area_type: GridInput.AreaType = GridInput.AreaType.Rectangle
@export var style: RenderStyle = RenderStyle.RandomBuilding
@export_color_no_alpha var color: Color
@export_group("Fields")
@export var field_requirements: Array[FieldRequirement] = []
@export var field_emissions: Array[FieldEmission] = []
@export_group("Resources")
@export var resource_requirements: Array[ResourceAmount] = []
@export var resource_consumption: Array[ResourceAmount] = []
@export var resource_prouction: Array[ResourceAmount] = []
@export var resource_stockpiles: Array[ResourceAmount] = []
@export_group("Linkages")
@export var upgrade_paths: Array[BuildingData] = []

View File

@ -0,0 +1 @@
uid://y688w7tmv2dr

View File

@ -0,0 +1,21 @@
extends Resource
class_name FieldEmission
enum Falloff {
Linear,
Flat
}
@export var field: Grid.Field
@export var amount: int = 10
@export var range: float = 3
@export var falloff: Falloff = Falloff.Linear
func get_field_value_for_distance(distance: float) -> int:
if distance == 0: return 0
match falloff:
Falloff.Linear:
return max(0, floor(remap(distance, 0, range, amount, 1)))
Falloff.Flat: return amount if distance <= range else 0
return 0

View File

@ -0,0 +1 @@
uid://cggmew2iau84h

View File

@ -0,0 +1,11 @@
class_name FieldComparison
extends FieldRequirement
enum Operation {
LessThan,
GreaterThan
}
@export var field_left: Grid.Field
@export var operation: Operation
@export var field_right: Grid.Field

View File

@ -0,0 +1 @@
uid://bi1mtw4wldwbl

View File

@ -0,0 +1,5 @@
class_name FieldMax
extends FieldRequirement
@export var field: Grid.Field
@export var max: int = 0

View File

@ -0,0 +1 @@
uid://5h2g03dsx026

View File

@ -0,0 +1,5 @@
class_name FieldMin
extends FieldRequirement
@export var field: Grid.Field
@export var min: int = 0

View File

@ -0,0 +1 @@
uid://b3ly4vy7xaynq

View File

@ -0,0 +1,6 @@
class_name FieldRange
extends FieldRequirement
@export var field: Grid.Field
@export var min: int = 0
@export var max: int = 0

View File

@ -0,0 +1 @@
uid://bgq3m714l64fl

View File

@ -0,0 +1,39 @@
extends Resource
class_name FieldRequirement
func is_satisfied_at_position(grid: Grid, pos: Vector2i) -> bool:
match self.get_script():
FieldMin:
var req = self as FieldMin
var value = grid.get_field_value_at(req.field, pos)
var min = req.min
return value >= min
FieldMax:
var req = self as FieldMax
var value = grid.get_field_value_at(req.field, pos)
var max = req.max
return value <= max
FieldRange:
var req = self as FieldMax
var value = grid.get_field_value_at(req.field, pos)
var min = req.min
var max = req.max
return min <= value <= max
FieldComparison:
var req = self as FieldComparison
var left = grid.get_field_value_at(req.field_left, pos)
var right = grid.get_field_value_at(req.field_right, pos)
match req.operation:
FieldComparison.Operation.LessThan: left < right
FieldComparison.Operation.GreaterThan: left > right
assert(false, "Unknown Field Requirement!")
return false
#var current_field_value = grid.get_field_value_at(requirement.field, tile_pos)
#if requirement.enforce_min && current_field_value < requirement.minimum: return false
#if requirement.enforce_max && current_field_value > requirement.maximum: return false
return true

View File

@ -0,0 +1 @@
uid://c2winf4nct0u7

View File

@ -0,0 +1,6 @@
extends Resource
class_name ResourceAmount
@export var resource: ResourceController.ResourceType
@export var amount: int = 0

View File

@ -0,0 +1 @@
uid://nroinmreopp4

View File

@ -0,0 +1,38 @@
[gd_scene load_steps=2 format=3 uid="uid://botck0aro5i65"]
[ext_resource type="Script" uid="uid://cf3f8iyagxl08" path="res://Scripts/ResourceTracker.gd" id="1_qky28"]
[node name="PanelContainer" type="PanelContainer" node_paths=PackedStringArray("bar", "name_label", "value_label", "changes")]
script = ExtResource("1_qky28")
bar = NodePath("ProgressBar")
name_label = NodePath("MarginContainer/HBoxContainer/Name")
value_label = NodePath("MarginContainer/HBoxContainer/Values")
changes = NodePath("MarginContainer/HBoxContainer/Changes")
decreased_color = Color(0.93333334, 0.39215687, 0.39215687, 1)
increased_color = Color(0.6627451, 0.7764706, 0.5647059, 1)
[node name="ProgressBar" type="ProgressBar" parent="."]
layout_mode = 2
size_flags_vertical = 1
value = 50.0
show_percentage = false
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="Name" type="Label" parent="MarginContainer/HBoxContainer"]
layout_mode = 2
text = "Undefined"
[node name="Values" type="Label" parent="MarginContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Undefined"
horizontal_alignment = 1
[node name="Changes" type="Label" parent="MarginContainer/HBoxContainer"]
layout_mode = 2
text = "undefined"

View File

@ -0,0 +1,27 @@
extends Button
class_name BuildButton
enum CreationAction {
Reservation,
Creation,
}
enum CursorStyle {
Single,
Area,
Line
}
#@export var building: Resource
@export var cursor_style: CursorStyle
@export var creation_action: CreationAction
@export var building: BuildingData
var menu: BuildMenu
func _ready():
menu = Util.find_parent_type(self, BuildMenu)
text = building.tile_name
func _pressed():
menu.build_button_pressed(self)

View File

@ -0,0 +1 @@
uid://p8y4cfg2aonj

View File

@ -0,0 +1,34 @@
extends VBoxContainer
class_name BuildMenu
@export var grid_input: GridInput
@export var grid: Grid
func build_button_pressed(button: BuildButton):
grid_input.request_area(
button.building,
request_confirmed,
request_cancelled,
GridInput.Style.Build,
button.building.area_type,
false
)
func tile_is_valid_at_location(building: BuildingData, tile_pos: Vector2i) -> bool:
for requirement in building.field_requirements:
if !requirement.is_satisfied_at_position(self.grid, tile_pos):
return false
return true
func request_confirmed(building: BuildingData, area: Rect2i) -> void:
for x in range(area.position.x, area.position.x + area.size.x):
for y in range(area.position.y, area.position.y + area.size.y):
if !tile_is_valid_at_location(building, Vector2i(x, y)): continue
var new_tile = Building.new(Vector2i(x, y), Vector2i.ONE, building)
grid.add_child(new_tile)
func request_cancelled(building: BuildingData) -> void:
pass

View File

@ -0,0 +1 @@
uid://d1lhn37ijatdp

206
Scripts/Building.gd 100644
View File

@ -0,0 +1,206 @@
@tool
extends TileTransform
class_name Building
var triangle_points = PackedVector2Array([
Vector2(0, -20) * 0.85 + Vector2.DOWN * 3,
Vector2(-20, 15) * 0.85 + Vector2.DOWN * 3,
Vector2(20, 15) * 0.85 + Vector2.DOWN * 3,
Vector2(0, -20) * 0.85 + Vector2.DOWN * 3,
])
var history: Array[BuildingData] = []
var data: BuildingData = null
func attempt_upgrade(new_data: BuildingData) -> bool:
var old_data = data
for resource_requirement in new_data.resource_requirements:
var resource = resource_requirement.resource
var required = resource_requirement.amount
var current = ResourceController.get_resource_value(resource)
if current < required:
return false
for field_requirement in new_data.field_requirements:
if !field_requirement.is_satisfied_at_position(self.grid, self.tile_pos):
return false
for resource_requirement in new_data.resource_requirements:
var resource = resource_requirement.resource
var required = resource_requirement.amount
ResourceController.consume_resource(resource, required)
grid.unregister_building(self)
for storage in data.resource_stockpiles:
ResourceController.remove_storage(storage)
data = new_data
grid.register_building(self)
for storage in data.resource_stockpiles:
ResourceController.add_storage(storage)
queue_redraw()
history.push_front(old_data)
return true
func attempt_upgrades() -> bool:
if randf() > 0.1: return false
for upgrade_path in data.upgrade_paths:
if attempt_upgrade(upgrade_path):
return true
return false
func _init(_tile_pos: Vector2i, _size: Vector2i, building_data: BuildingData):
self.data = building_data
self.tile_pos = _tile_pos
self.size = _size
func _ready():
super._ready()
grid.register_building(self)
for storage in data.resource_stockpiles:
ResourceController.add_storage(storage)
ResourceController.upgrade.connect(_upgrade_downgrade)
ResourceController.produce.connect(_resource_produce)
ResourceController.consume.connect(_resource_consume)
func _downgrade_or_die():
while history.size() > 0:
var downgrade_data = history.pop_front()
if attempt_upgrade(downgrade_data):
history.pop_front()
return
queue_free()
func _upgrade_downgrade():
attempt_upgrades()
if death_timer >= max_death:
_downgrade_or_die()
var death_timer = 0
var max_death = 5
func _resource_produce():
for resource_data in data.resource_prouction:
ResourceController.add_resource(resource_data.resource, resource_data.amount)
func _resource_consume():
var good_cycle = true
for resource_data in data.resource_consumption:
good_cycle = good_cycle and ResourceController.consume_resource(
resource_data.resource,
resource_data.amount
)
# i know it says resource consumption but this is also where we make sure
# our fields still make sense, okay?
for field_requirement in data.field_requirements:
if !field_requirement.is_satisfied_at_position(self.grid, self.tile_pos):
good_cycle = false
#var field_value = grid.get_field_value_at(field_requirement.field, tile_pos)
#if field_requirement.enforce_min and field_value < field_requirement.minimum:
#good_cycle = false
#if field_requirement.enforce_max and field_value > field_requirement.maximum:
#good_cycle = false
if !good_cycle:
death_timer += 1
queue_redraw()
elif death_timer != 0:
death_timer = 0
queue_redraw()
func _draw():
seed(get_instance_id())
match data.style:
BuildingData.RenderStyle.RandomBuilding: _draw_building()
BuildingData.RenderStyle.Full: _render_full()
BuildingData.RenderStyle.Outline: _render_outline()
BuildingData.RenderStyle.Triangle: _render_triangle()
BuildingData.RenderStyle.Circles: _render_circles()
if death_timer > 0: _draw_death_timer_overlay()
func _exit_tree():
grid.unregister_building(self)
for storage in data.resource_stockpiles:
ResourceController.remove_storage(storage)
ResourceController.upgrade.disconnect(_upgrade_downgrade)
ResourceController.produce.disconnect(_resource_produce)
ResourceController.consume.disconnect(_resource_consume)
func randf_norm():
return (randf() + randf() + randf() + randf() + randf()) / 5.0
func random_box_within(bounds: Rect2, min_size: float = 0.2, max_size: float = 0.6) -> Rect2:
var size = bounds.size * Vector2(
randf_norm() * (max_size - min_size) + min_size,
randf_norm() * (max_size - min_size) + min_size
)
var position = (bounds.size - size) * Vector2(randf(), randf())
return Rect2(bounds.position + position, size)
func _get_render_bounds() -> Rect2:
var dimensions = self.size * (self.grid.cell_size if self.grid != null else 100)
return Rect2(dimensions / -2.0, dimensions)
func _draw_building():
var render_bounds = _get_render_bounds()
var bottom_box = random_box_within(render_bounds, 0.2, 0.6)
#draw_rect(_get_render_bounds(), data.color.darkened(0.5), true)
draw_rect(bottom_box, self.data.color, true)
#draw_rect(render_bounds, self.data.color, false, 2)
_draw_rect_inset(render_bounds, data.color, 4)
func _render_full():
draw_rect(_get_render_bounds(), data.color, true)
func _render_outline():
var bounds = _get_render_bounds().grow(-8)
var left = bounds.grow_side(SIDE_RIGHT, -(bounds.size.y - 4))
var right = bounds.grow_side(SIDE_LEFT, -(bounds.size.y - 4))
var top = bounds.grow_side(SIDE_BOTTOM, -(bounds.size.y - 4))
var bottom = bounds.grow_side(SIDE_TOP, -(bounds.size.y - 4))
draw_dashed_line(bounds.position, bounds.position + Vector2.RIGHT * bounds.size.x, data.color, 4, 6)
draw_dashed_line(bounds.position, bounds.position + Vector2.DOWN * bounds.size.y, data.color, 4, 6)
draw_dashed_line(bounds.position + bounds.size, bounds.position + bounds.size + Vector2.LEFT * bounds.size.x, data.color, 4, 6)
draw_dashed_line(bounds.position + bounds.size, bounds.position + bounds.size + Vector2.UP * bounds.size.y, data.color, 4, 6)
func _render_triangle():
draw_colored_polygon(triangle_points, data.color)
func _render_circles():
var bounds = _get_render_bounds()
for idx in range(3):
var radius = min(bounds.size.x, bounds.size.y) / 4.0 * randf_norm()
var inner_bounds = bounds.grow(-radius)
var point = inner_bounds.position \
+ Vector2(randf(), randf()) * inner_bounds.size
draw_circle(point, radius, data.color, true, -1, true)
func _draw_rect_inset(rect: Rect2, color: Color, width: float):
var left = rect.grow_side(SIDE_RIGHT, -(rect.size.y - width))
var right = rect.grow_side(SIDE_LEFT, -(rect.size.y - width))
var top = rect.grow_side(SIDE_BOTTOM, -(rect.size.y - width))
var bottom = rect.grow_side(SIDE_TOP, -(rect.size.y - width))
draw_rect(left, color, true)
draw_rect(right, color, true)
draw_rect(top, color, true)
draw_rect(bottom, color, true)
func _draw_death_timer_overlay():
var bounds = _get_render_bounds()
var font_size = 18
var color = Color.GOLDENROD if death_timer < max_death * 0.8 else Color("ee6464")
var outline_color = Color.BLACK if death_timer < max_death * 0.8 else Color.BLACK
draw_colored_polygon(triangle_points, color)
draw_polyline(triangle_points, outline_color, 3.0, true)
draw_polyline(triangle_points, color, 1.0, true)
var height = ThemeDB.fallback_font.get_height(font_size)
draw_string(
ThemeDB.fallback_font,
Vector2.LEFT * 5.0 + Vector2.DOWN * 11.5,
"!",
HORIZONTAL_ALIGNMENT_CENTER,
10.5,
font_size,
outline_color
)

View File

@ -0,0 +1 @@
uid://dskk0dwdutvv3

View File

@ -0,0 +1,8 @@
extends Label
func _ready():
Clock.day_passed.connect(_update_text)
_update_text()
func _update_text():
text = Clock.get_date_string()

View File

@ -0,0 +1 @@
uid://rr8s2u7xswtc

46
Scripts/Clock.gd 100644
View File

@ -0,0 +1,46 @@
extends Node
const months = [
"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"
]
var counter: float = 0
const day_length = 2
var day_count: int = 0
var month = 1
var date = 1
var year = 2000
signal day_passed
signal resource_produce
signal resource_consume
func _process(delta: float):
counter += delta
if counter > day_length:
counter -= day_length
day_count += 1
date += 1
if date == 31:
date -= 30
month += 1
if month == 13:
month -= 12
year += 1
resource_produce.emit()
resource_consume.emit()
day_passed.emit()
func _nth_str(n: int):
if n == 0: return "0th"
if n >= 4 and n <= 20: return str(n) + "th"
if n % 10 == 1: return "1st"
if n % 10 == 2: return "2nd"
if n % 10 == 3: return "3rd"
return str(n) + "th"
func get_date_string():
return months[month - 1] + " " + _nth_str(date) + ", " + str(year)

View File

@ -0,0 +1 @@
uid://csx4bl2w2o10d

View File

@ -0,0 +1,132 @@
extends Node2D
class_name CursorPool
enum AnimationState {
Normal, # lerps box center and size to desired.
Exploding, # Normal but diff lerp speeds.
Area, # lerps each box side to desired box side
Fading, # standard box motion, opacity fades slowly.
}
class Cursor:
var box: Rect2
var opacity: float
var desired_box: Rect2
var desired_opacity: float
var color: Color
var animation: AnimationState = AnimationState.Normal
var cursors: Array[Cursor] = []
var current_cursor: Cursor = null
func new_cursor(color: Color) -> Cursor:
var cursor = Cursor.new()
cursors.append(cursor)
if cursors.size() > 10: cursors.remove_at(0)
cursor.box = get_viewport_rect()
cursor.box.size = Vector2.ONE * max(cursor.box.size.x, cursor.box.size.y)
cursor.box = Rect2(cursor.box.position + cursor.box.size / -2.0, cursor.box.size).grow(100)
cursor.opacity = -2.0
cursor.animation = AnimationState.Normal
cursor.desired_box = cursor.box
cursor.desired_opacity = 1.0
cursor.color = color
current_cursor = cursor
return cursor
# cursor removal type beats.
func fade_out() -> void:
if current_cursor == null: return
current_cursor.animation = AnimationState.Fading
current_cursor.desired_opacity = 0.0
func explode() -> void:
if current_cursor == null: return
current_cursor.animation = AnimationState.Exploding
current_cursor.desired_box = current_cursor.desired_box.grow(10)
current_cursor.desired_opacity = 0.0
# override / util
func _process(delta) -> void:
for d in cursors:
match d.animation:
AnimationState.Normal: _update_display_animation_active(d, delta)
AnimationState.Exploding: _update_display_animation_exploding(d, delta)
AnimationState.Fading: _update_display_animation_fading(d, delta)
AnimationState.Area: _update_display_animation_area(d, delta)
queue_redraw()
func _draw():
for d in cursors:
draw_rect(d.box, _lerp_opacity(d.color, d.opacity), true)
func _lerp_opacity(c: Color, t: float) -> Color:
return Color(c.r, c.g, c.b, c.a * t)
# === Display Animations
func _update_display_animation_active(d: Cursor, delta):
var old_size = d.box.size
var desired_size = d.desired_box.size
var new_size = lerp(old_size, desired_size, delta * 30 * Util.animation_speed)
#if old_size.length_squared() > desired_size.length_squared():
#new_size = lerp(old_size, desired_size, delta * 30 * animation_speed)
#else:
#new_size = lerp(old_size, desired_size, delta * 30 * animation_speed)
var old_center = d.box.get_center()
var desired_center = d.desired_box.get_center()
var new_center = lerp(old_center, desired_center, delta * 50 * Util.animation_speed)
d.box = Rect2(new_center - new_size / 2.0, new_size)
d.opacity = lerp(d.opacity, d.desired_opacity, delta * 20 * Util.animation_speed)
func _update_display_animation_exploding(d: Cursor, delta):
var old_size = d.box.size
var desired_size = d.desired_box.size
var new_size = lerp(old_size, desired_size, delta * 20 * Util.animation_speed)
var old_center = d.box.get_center()
var desired_center = d.desired_box.get_center()
var new_center = lerp(old_center, desired_center, delta * 50 * Util.animation_speed)
d.box = Rect2(new_center - new_size / 2.0, new_size)
d.opacity = lerp(d.opacity, d.desired_opacity, delta * 15 * Util.animation_speed)
func _update_display_animation_fading(d: Cursor, delta):
var current_top = min(d.box.position.y, d.box.position.y + d.box.size.y)
var current_bottom = max(d.box.position.y, d.box.position.y + d.box.size.y)
var current_left = min(d.box.position.x, d.box.position.x + d.box.size.x)
var current_right = max(d.box.position.x, d.box.position.x + d.box.size.x)
var desired_top = min(d.desired_box.position.y, d.desired_box.position.y + d.desired_box.size.y)
var desired_bottom = max(d.desired_box.position.y, d.desired_box.position.y + d.desired_box.size.y)
var desired_left = min(d.desired_box.position.x, d.desired_box.position.x + d.desired_box.size.x)
var desired_right = max(d.desired_box.position.x, d.desired_box.position.x + d.desired_box.size.x)
var new_top = lerp(current_top, desired_top, delta * Util.animation_speed * 40)
var new_bottom = lerp(current_bottom, desired_bottom, delta * Util.animation_speed * 40)
var new_left = lerp(current_left, desired_left, delta * Util.animation_speed * 40)
var new_right = lerp(current_right, desired_right, delta * Util.animation_speed * 40)
d.box = Rect2(
new_left,
new_top,
new_right - new_left,
new_bottom - new_top
)
d.opacity = lerp(d.opacity, d.desired_opacity, delta * 10 * Util.animation_speed)
func _update_display_animation_area(d: Cursor, delta):
var current_top = min(d.box.position.y, d.box.position.y + d.box.size.y)
var current_bottom = max(d.box.position.y, d.box.position.y + d.box.size.y)
var current_left = min(d.box.position.x, d.box.position.x + d.box.size.x)
var current_right = max(d.box.position.x, d.box.position.x + d.box.size.x)
var desired_top = min(d.desired_box.position.y, d.desired_box.position.y + d.desired_box.size.y)
var desired_bottom = max(d.desired_box.position.y, d.desired_box.position.y + d.desired_box.size.y)
var desired_left = min(d.desired_box.position.x, d.desired_box.position.x + d.desired_box.size.x)
var desired_right = max(d.desired_box.position.x, d.desired_box.position.x + d.desired_box.size.x)
var new_top = lerp(current_top, desired_top, delta * Util.animation_speed * 40)
var new_bottom = lerp(current_bottom, desired_bottom, delta * Util.animation_speed * 40)
var new_left = lerp(current_left, desired_left, delta * Util.animation_speed * 40)
var new_right = lerp(current_right, desired_right, delta * Util.animation_speed * 40)
d.box = Rect2(
new_left,
new_top,
new_right - new_left,
new_bottom - new_top
)
d.opacity = lerp(d.opacity, d.desired_opacity, delta * 20 * Util.animation_speed)

View File

@ -0,0 +1 @@
uid://du3m15i8ahlu5

View File

@ -0,0 +1,21 @@
extends VBoxContainer
@export var grid: Grid
@export var overlay_enabled_button: Button
@export var overlay_selection_button: OptionButton
@export var overlay_display_values: Button
func _ready():
var grid_fields = Grid.Field.keys()
for idx in range(grid_fields.size()):
overlay_selection_button.add_item(grid_fields[idx], idx)
overlay_enabled_button.toggled.connect(update_overlay)
overlay_display_values.toggled.connect(update_overlay)
overlay_selection_button.item_selected.connect(update_overlay)
func update_overlay(data):
grid.debug_overlay_display_values = overlay_display_values.button_pressed
if !overlay_enabled_button.button_pressed:
grid.disable_debug_field_overlay()
else:
grid.enable_field_debug_overlay(overlay_selection_button.selected)

View File

@ -0,0 +1 @@
uid://cj8bj60oyrc4f

View File

@ -1,20 +0,0 @@
@tool
extends Node2D
class_name WorldEntity
var grid: Grid
func _ready():
if Engine.is_editor_hint():
grid = get_tree().edited_scene_root.find_child("Grid")
else:
grid = $/root/Root/Grid
Util.find(Grid)
func _process(_delta):
pass
func _draw():
draw_circle(Vector2.ZERO, 100, Color.WHITE)

View File

@ -1 +0,0 @@
uid://denhgj0vxywle

View File

@ -0,0 +1,4 @@
extends Label
func _process(delta: float) -> void:
set_text("FPS " + str(Engine.get_frames_per_second()))

View File

@ -0,0 +1 @@
uid://j6fc2qc5t3qa

View File

@ -10,6 +10,8 @@ extends Node2D
set(val):
cell_size = val
_calc_dims()
@export var grid_color: Color = Color.DARK_GREEN
@export var line_color: Color = Color.DARK_GREEN.darkened(0.2)
var total_width: int
var total_height: int
@ -17,54 +19,91 @@ var total_height: int
var thickness: int
var off: Vector2
var residents_field: Array[int]
enum Field {
Logistics,
Residents,
Commercial,
Foragable,
Forested
}
var fields: Dictionary[Field, Array] = {}
@onready var selection_manager: SelectionManager = Util.find(SelectionManager)
func ensure_field(field: Field):
if field in fields: return
fields[field] = []
fields[field].resize(cells ** 2)
for idx in range(cells ** 2): fields[field][idx] = 0
func _enter_tree():
_calc_dims()
func _ready():
_calc_dims()
Engine.is_editor_hint()
residents_field.resize(cells ** 2)
for idx in len(residents_field):
residents_field[idx] = 0
func _calc_dims():
total_width = cells * cell_size
total_height = cells * cell_size
thickness = 1
thickness = 2
off = Vector2(total_width / -2, total_height / -2)
func _process(_delta):
queue_redraw()
func _draw():
var r = Rect2(off, Vector2(total_width, total_height))
draw_rect(r, Color("222222"), true)
var line_color = Color(1, 1, 1, 0.3)
draw_rect(r, grid_color, true)
for i in range(cells + 1):
draw_line(Vector2(i * cell_size, 0) + off, Vector2(i * cell_size, total_height) + off, line_color, thickness, false)
for i in range(cells + 1):
draw_line(Vector2(0, i * cell_size) + off, Vector2(total_width, i * cell_size) + off, line_color, thickness, false)
if !debug_overlay_enabled: return
if !fields.has(debug_overlay_field): return
var field = fields[debug_overlay_field]
var field_min = field.min()
var field_max = field.max()
for x in range(cells):
for y in range(cells):
var world_pos = Vector2i(x, y)
var tile = _get_tile_at_tile_pos(world_pos)
if tile == null:
continue
var t = Rect2(
tile2world(world_pos),
Vector2.ONE * cell_size
)
draw_rect(t, Color("773322"))
var index = tile_pos2index(Vector2i(x, y))
if field[index] == 0: continue
var true_value = field[index]
if true_value <= 0: continue
var t = inverse_lerp(0, field_max if true_value > 0 else abs(field_min), abs(true_value))
var grad = overlay_gradient if true_value > 0 else overlay_gradient_negative
var font_grad = overlay_font_color_gradient if true_value > 0 else overlay_font_color_gradient
var color = grad.sample(t)
var world_rect = tile2world_rect(Rect2i(x, y, 1, 1))
draw_rect(world_rect, color, true)
func tile2world(tile: Vector2i) -> Vector2i:
if !debug_overlay_display_values: continue
var world_pos = self.tile2world(Vector2i(x, y))
var debug_str = str(field[index])
draw_string(
ThemeDB.fallback_font,
world_pos + Vector2.DOWN * cell_size / 2.0,
debug_str,
HORIZONTAL_ALIGNMENT_CENTER,
cell_size,
10,
font_grad.sample(t)
)
#var tile = _get_tile_at_tile_pos(world_pos)
#if tile == null:
#continue
#print(tile)
#var t = Rect2(
#tile2world(world_pos),
#Vector2.ONE * cell_size
#)
#draw_rect(t, Color("773322"))
func tile2world(tile: Vector2i) -> Vector2:
return Vector2(tile) * cell_size + off
func tile2world_rect(tile: Rect2i) -> Rect2:
func tile2world_rect(tile: Rect2) -> Rect2:
return Rect2(Vector2(tile.position) * cell_size + off, tile.size * cell_size)
func tile2world_size(tile_size: Vector2i) -> Vector2:
@ -93,13 +132,13 @@ func quantize_on_objects(world_position: Vector2) -> Rect2:
return tile.get_worldbox()
return quantize(world_position, Vector2.ONE)
func _get_tile_at_tile_pos(pos: Vector2i) -> TileTransform:
func _get_building_at(pos: Vector2i) -> Building:
for tile in things:
if tile.get_tilebox().has_point(pos):
return tile
return null
func _get_tile_at_world_pos(pos: Vector2) -> TileTransform:
func _get_tile_at_world_pos(pos: Vector2) -> Building:
#var world_pos = world2tile_f(pos)
for tile in things:
if tile.get_worldbox().has_point(pos):
@ -124,15 +163,84 @@ var things_dict: Dictionary = {}
func tile_pos2index(pos: Vector2i) -> int:
return pos.x + pos.y * self.cells
func idnex2tile_pos(idx: int) -> Vector2i:
func index2tile_pos(idx: int) -> Vector2i:
return Vector2i(
idx % self.cells,
floor(idx / self.cells)
)
func register_tile(tile: TileTransform) -> void:
things.append(tile)
func increase_field_value(emissions_data: FieldEmission, position: Vector2i):
ensure_field(emissions_data.field)
var field = fields[emissions_data.field]
# field[tile_pos2index(position)] = max(amt, field[tile_pos2index(position)])
for x_offset in range(- emissions_data.range - 1, emissions_data.range + 1):
for y_offset in range(- emissions_data.range - 1, emissions_data.range + 1):
var offset = Vector2i(x_offset, y_offset)
var new_pos = position + offset
if new_pos.x < 0: continue
if new_pos.y < 0: continue
if new_pos.x >= cells: continue
if new_pos.y >= cells: continue
var field_addition = emissions_data.get_field_value_for_distance(offset.length())
if field_addition == 0: continue
var index = tile_pos2index(new_pos)
field[index] += field_addition
func decrease_field_Value(emissions_data: FieldEmission, position: Vector2i):
ensure_field(emissions_data.field)
var field = fields[emissions_data.field]
# field[tile_pos2index(position)] = max(amt, field[tile_pos2index(position)])
for x_offset in range(- emissions_data.range - 1, emissions_data.range + 1):
for y_offset in range(- emissions_data.range - 1, emissions_data.range + 1):
var offset = Vector2i(x_offset, y_offset)
var new_pos = position + offset
if new_pos.x < 0: continue
if new_pos.y < 0: continue
if new_pos.x >= cells: continue
if new_pos.y >= cells: continue
var field_addition = emissions_data.get_field_value_for_distance(offset.length())
if field_addition == 0: continue
var index = tile_pos2index(new_pos)
field[index] -= field_addition
var overlay_gradient: Gradient = preload("res://Gradients/OverlayBasic.tres")
var overlay_gradient_negative: Gradient = preload("res://Gradients/OverlayBasicNegative.tres")
var overlay_font_color_gradient: Gradient = preload("res://Gradients/OverlayBasicFontColor.tres")
@export var debug_overlay_enabled: bool = true
@export var debug_overlay_field: Field = Field.Logistics
@export var debug_overlay_display_values: bool = false
func enable_field_debug_overlay(field: Field):
debug_overlay_enabled = true
debug_overlay_field = field
queue_redraw()
func disable_debug_field_overlay():
debug_overlay_enabled = false
queue_redraw()
func unregister_building(tile: Building) -> void:
things.erase(tile)
var tilebox = tile.get_tilebox()
for x_off in range(tilebox.size.x):
for y_off in range(tilebox.size.y):
for emission in tile.data.field_emissions:
decrease_field_Value(emission, tilebox.position + Vector2i(x_off, y_off))
queue_redraw()
func register_building(tile: Building) -> void:
things.append(tile)
var tilebox = tile.get_tilebox()
for x_off in range(tilebox.size.x):
for y_off in range(tilebox.size.y):
for emission in tile.data.field_emissions:
increase_field_value(emission, tilebox.position + Vector2i(x_off, y_off))
queue_redraw()
func remove_tile(tile: TileTransform) -> void:
things.erase(tile)
func get_field_value_at(field: Field, tile_pos: Vector2i):
if field not in fields: return 0
var value = fields[field][tile_pos2index(tile_pos)]
return value

View File

@ -1,213 +1,207 @@
extends Node2D
class_name GridInput
@onready var grid: Grid = $/root/Root/Grid
@export var highlight_color: Color = Color(1, 1, 1, 0.2)
@export var deletion_color: Color = Color(1, 1, 1, 0.2)
var animation_speed = 0.8
enum AnimationState {
Active,
Fading,
Exploding
}
enum CursorMode {
Selection,
Deletion
}
class Display:
var mode: CursorMode
var box: Rect2
var desired_box: Rect2
var opacity: float
var confirmed_callback: Callable
var cancelled_callback: Callable
var dragging: bool = false
var drag_from: Rect2
var state: AnimationState = AnimationState.Fading
var display_count = 10
var displays: Array[Display] = []
var display_idx = -1
var display: Display:
get():
return displays[display_idx] if display_idx >= 0 else null
func new_display():
if display_idx < 0:
display_idx += display_count
display_idx += 1
display_idx = display_idx % display_count
display.dragging = false
display.box = get_viewport_rect()
display.box.size = Vector2.ONE * max(display.box.size.x, display.box.size.y)
display.box = Rect2(display.box.position + display.box.size / -2.0, display.box.size).grow(100)
display.opacity = -2.0
display.state = AnimationState.Active
display.desired_box = display.box
func end_display():
if display == null: return
if display.state == AnimationState.Active:
display.state = AnimationState.Fading
if display.state == AnimationState.Exploding:
display.desired_box = display.desired_box.grow(30)
display_idx -= display_count
var left_dragging = false
var left_mouse_down = false
var left_mouse_down_start_pos: Vector2 = Vector2.ZERO
func _is_mouse_pos_significant() -> bool:
return (get_local_mouse_position() - left_mouse_down_start_pos).length_squared() > 50
#eventually, replace this weird shit with an array of old rects that are fading out
#let them fade out, and just remove them. have a method to abandon the current box
#and start a new one that just follows the normal box-booting procedure.
#if you're not in the grid, it simply wont be created yet. have to have a has_box prop
#or something like that. but this is good enough for now
var highlight_color: Color = Color(0.075, 0.536, 0.75, 0.38)
var build_color: Color = Color(0.087, 0.62, 0.087, 0.514)
var deletion_color: Color = Color(0.76, 0.237, 0.106, 0.4)
var current_color = highlight_color
var cursor_pool: CursorPool
func _ready():
selection_manager = Util.find(SelectionManager)
displays.resize(display_count)
for idx in range(displays.size()):
displays[idx] = Display.new()
displays[idx].opacity = 0.0
displays[idx].state = AnimationState.Fading
cursor_pool = Util.find_child_type(self, CursorPool)
mouse_in_grid = grid.contains_world_pos(get_local_mouse_position())
if mouse_in_grid:
new_display()
func _lerp_opacity(c: Color, t: float) -> Color:
return Color(c.r, c.g, c.b, c.a * t)
func update_display_animations(delta):
for d in displays:
var old_size = d.box.size
var desired_size = d.desired_box.size
var new_size = 0.0
match d.state:
AnimationState.Exploding:
new_size = lerp(old_size, desired_size, delta * 3 * animation_speed)
AnimationState.Active, \
AnimationState.Fading:
if old_size.length_squared() > desired_size.length_squared():
new_size = lerp(old_size, desired_size, delta * 30 * animation_speed)
else:
new_size = lerp(old_size, desired_size, delta * 30 * animation_speed)
var old_center = d.box.get_center()
var desired_center = d.desired_box.get_center()
var new_center = lerp(old_center, desired_center, delta * 50 * animation_speed)
d.box = Rect2(new_center - new_size / 2.0, new_size)
match d.state:
AnimationState.Fading:
d.opacity = lerp(d.opacity, 0.0, delta * 10 * animation_speed)
AnimationState.Active:
d.opacity = lerp(d.opacity, 1.0, delta * 20 * animation_speed)
AnimationState.Exploding:
d.opacity = lerp(d.opacity, -1.0, delta * 5 * animation_speed)
var mouse_in_grid: bool = false
var mousing_over: Rect2
func _process(delta):
queue_redraw()
var mouse = get_local_mouse_position()
var new_mousing_over = grid.quantize_on_objects(mouse)
var new_mouse_in_grid = grid.contains_world_pos(mouse)
if mouse_in_grid && !new_mouse_in_grid:
end_display()
if !mouse_in_grid && new_mouse_in_grid:
new_display()
display.mode = CursorMode.Deletion
if new_mousing_over != mousing_over && display == null && new_mouse_in_grid:
new_display()
mouse_in_grid = new_mouse_in_grid
mousing_over = new_mousing_over
update_display_animations(delta)
# only do anything new if we have a mouse on the grid!
if !mouse_in_grid: return
if display == null: return
display.desired_box = mousing_over
func _draw():
#draw_rect(mousing_over.grow(-8), Color.FIREBRICK, true)
for d in displays:
match d.mode:
CursorMode.Selection:
draw_rect(d.box, _lerp_opacity(highlight_color, d.opacity), true)
CursorMode.Deletion:
draw_rect(d.box, _lerp_opacity(deletion_color, d.opacity), true)
enum State {
# Selection will automatically go do selection things
Selection,
# whereas these hoes will just call callbacks.
LineDrag,
Area,
enum AreaType {
Rectangle,
Line,
None,
}
var current_marquee_type: AreaType = AreaType.Rectangle
var state: State = State.Selection
var selection_manager: SelectionManager
func _begin_drag(pos: Vector2):
display.drag_from
print("drag from", pos)
func _dragging(pos: Vector2):
pass
func _end_drag(pos: Vector2):
print("to", pos)
func _click(pos: Vector2):
print("click at", pos)
if display == null:
new_display()
display.state = AnimationState.Exploding
end_display()
var tile = grid._get_tile_at_world_pos(pos)
if tile == null:
selection_manager.clear()
return
selection_manager.select_array([tile])
func _double_click(pos: Vector2):
pass
func _right_click(pos: Vector2):
pass
# === RAW MOUSE EVENTS ===
# first we process inputs raw and separate them out into something digestable
# This uses some state data!
var _left_dragging = false
var _left_mouse_down = false
var _left_mouse_down_start_pos: Vector2 = Vector2.ZERO
func __is_mouse_pos_significant() -> bool:
return (get_local_mouse_position() - _left_mouse_down_start_pos).length_squared() > 50
func _input(event: InputEvent):
if event is InputEventMouseMotion:
if left_mouse_down:
if not left_dragging and _is_mouse_pos_significant():
left_dragging = true
if _left_mouse_down:
if not _left_dragging and __is_mouse_pos_significant():
_left_dragging = true
_begin_drag(get_local_mouse_position())
elif left_dragging:
_dragging(get_local_mouse_position())
elif _left_dragging:
_update_drag(get_local_mouse_position())
else:
_update_hover(get_local_mouse_position())
elif event is InputEventMouseButton:
if event.button_index == 1:
left_mouse_down = event.pressed
_left_mouse_down = event.pressed
if event.pressed:
left_mouse_down_start_pos = get_local_mouse_position()
_left_mouse_down_start_pos = get_local_mouse_position()
else:
if left_dragging:
left_dragging = false
if _left_dragging:
_left_dragging = false
_end_drag(get_local_mouse_position())
else:
_click(get_local_mouse_position())
_left_click(get_local_mouse_position())
elif event.button_index == 2 && event.pressed:
_right_click(get_local_mouse_position())
# for now, lets pretend these are simple :)
func _left_click(pos: Vector2):
if !grid.contains_world_pos(pos): return
var tile_pos = grid.world2tile(pos)
_grid_clicked(tile_pos)
func _right_click(pos: Vector2):
_cancel_operation()
cursor_pool.explode()
if !mouse_in_grid: return
cursor_pool.new_cursor(current_color)
_update_cursor()
var mouse_in_grid: bool = false # TODO init this correctly lol
func __mouse_may_have_left_or_entered_grid(pos: Vector2):
var new_mouse_in_grid = grid.contains_world_pos(pos)
var mouse_entered_grid = new_mouse_in_grid && !mouse_in_grid
var mouse_left_grid = !new_mouse_in_grid && mouse_in_grid
mouse_in_grid = new_mouse_in_grid
if mouse_entered_grid: _mouse_enter_grid()
elif mouse_left_grid: _mouse_leave_grid()
func _update_hover(pos: Vector2):
__mouse_may_have_left_or_entered_grid(pos)
if !mouse_in_grid: return
_mouse_hover_grid(pos)
# while dragging will attempt to begin marquee selection
var in_marquee: bool = false
var marquee_start_tile: Vector2i = Vector2i.ZERO
func __get_current_marquee_area(pos: Vector2i):
var marquee_end_tile = grid.world2tile(pos)
match current_marquee_type:
AreaType.Rectangle:
return Rect2i(marquee_start_tile, Vector2i.ONE).merge(Rect2i(marquee_end_tile, Vector2i.ONE))
AreaType.Line:
var vertical = Rect2i(marquee_start_tile, Vector2i.ONE).merge(Rect2i(Vector2i(marquee_start_tile.x, marquee_end_tile.y), Vector2i.ONE))
var horizontal = Rect2i(marquee_start_tile, Vector2i.ONE).merge(Rect2i(Vector2i(marquee_end_tile.x, marquee_start_tile.y), Vector2i.ONE))
return vertical if vertical.get_area() > horizontal.get_area() else horizontal
func _begin_drag(pos: Vector2):
__mouse_may_have_left_or_entered_grid(pos)
if !mouse_in_grid: return
in_marquee = true
marquee_start_tile = grid.world2tile(pos)
_begin_marquee(marquee_start_tile)
func _update_drag(pos: Vector2):
__mouse_may_have_left_or_entered_grid(pos)
if !mouse_in_grid: return
if !in_marquee: return
var new_area = __get_current_marquee_area(pos)
_update_marquee(new_area)
func _end_drag(pos: Vector2):
if !in_marquee:
cursor_pool.new_cursor(current_color)
_update_cursor()
return
var final_area = __get_current_marquee_area(pos)
if !mouse_in_grid:
_cancel_marquee()
else:
_end_marquee(final_area)
in_marquee = false
# === PROCESSED GAME INTERACTION EVENTS ===
func _mouse_enter_grid():
if !in_marquee && !_left_dragging:
cursor_pool.new_cursor(current_color)
if in_marquee:
cursor_pool.new_cursor(current_color)
cursor_pool.current_cursor.animation = \
cursor_pool.AnimationState.Area
func _mouse_leave_grid():
cursor_pool.fade_out()
func _mouse_hover_grid(world_pos: Vector2):
_update_cursor()
func _cancel_operation():
clear_request()
func _begin_marquee(tile_pos: Vector2i):
cursor_pool.current_cursor.desired_box = \
grid.tile2world_rect(Rect2i(tile_pos, Vector2i.ONE))
cursor_pool.current_cursor.animation = CursorPool.AnimationState.Area
func _update_marquee(area: Rect2i):
cursor_pool.current_cursor.desired_box = \
grid.tile2world_rect(area)
func _end_marquee(area: Rect2i):
_area_selected(area)
cursor_pool.explode()
cursor_pool.new_cursor(current_color)
_update_cursor()
func _cancel_marquee():
cursor_pool.explode()
if !mouse_in_grid: return
cursor_pool.new_cursor(current_color)
func _grid_clicked(tile_pos: Vector2i):
_area_selected(Rect2i(tile_pos, Vector2i.ONE))
cursor_pool.explode()
cursor_pool.new_cursor(current_color)
_update_cursor()
pass
func _update_cursor(world_pos = get_local_mouse_position()):
cursor_pool.current_cursor.desired_box = \
grid.quantize_on_objects(world_pos)
enum Style {
Highlight,
Build,
Delete
}
class Request:
var context: Variant
var confirmed
var cancelled
var request: Request = null
var one_shot: bool = false
@export var selection_manager: SelectionManager
func _area_selected(area: Rect2i):
if request != null:
request.confirmed.call(request.context, area)
if one_shot: _reset()
return
if area.size == Vector2i.ONE:
var item = grid._get_building_at(area.position)
if item != null:
selection_manager.select_array([item])
return
if item == null:
selection_manager.clear()
func clear_request():
if request == null: return
request.cancelled.call(request.context)
request = null
_reset()
func request_area(ctx, confirm, cancel, style: Style, area_type: AreaType, one_shot: bool):
request = Request.new()
request.confirmed = confirm
request.cancelled = cancel
request.context = ctx
current_marquee_type = area_type
_set_style(style)
func _reset():
_set_style(Style.Highlight)
current_marquee_type = AreaType.Rectangle
func _set_style(style: Style):
match style:
Style.Highlight: current_color = highlight_color
Style.Build: current_color = build_color
Style.Delete: current_color = deletion_color

View File

@ -0,0 +1,113 @@
extends Node
enum ResourceType {
Logs,
Labor,
Berries,
Food
}
const res_names = {
#ResourceType.Logs: "Logs"
}
signal produce
signal consume
signal upgrade
signal resource_type_added
signal resource_stats_updated
class ResourceStats:
var max: int
var value: int
var delta: int
var stock: Dictionary[ResourceType, int] = {}
var storage: Dictionary[ResourceType, int] = {}
func add_storage(data: ResourceAmount):
ensure_resource(data.resource)
storage[data.resource] += data.amount
func remove_storage(data: ResourceAmount):
ensure_resource(data.resource)
storage[data.resource] -= data.amount
if stock[data.resource] > storage[data.resource]:
stock[data.resource] = storage[data.resource]
func _ready():
Clock.day_passed.connect(_tick_resources)
func _tick_resources():
var stats: Dictionary[ResourceType, ResourceStats] = {}
for resource in stock.keys():
var stat = ResourceStats.new()
stat.delta = -stock[resource]
stat.max = storage[resource]
stats[resource] = stat
produce.emit()
consume.emit()
for resource in stock.keys():
if !stats.has(resource):
var stat = ResourceStats.new()
stat.delta = stock[resource]
stat.max = storage[resource]
stats[resource] = stat
continue
stats[resource].delta += stock[resource]
# \/ this really should change here but like shrug
stats[resource].max = storage[resource]
for resource in stock.keys():
var max = storage[resource]
stock[resource] = clamp(stock[resource], 0, storage[resource])
stats[resource].value = stock[resource]
upgrade.emit()
for resource in stock:
if !stats.has(resource):
var stat = ResourceStats.new()
stat.value = stock[resource]
stat.delta = stock[resource]
stat.max = storage[resource]
stats[resource] = stat
continue
stats[resource].value = stock[resource]
stats[resource].max = storage[resource]
for resource in stats.keys():
var stat = stats[resource]
resource_stats_updated.emit(resource, stat)
func ensure_resource(resource: ResourceType):
if resource in stock: return
stock[resource] = 0
storage[resource] = 0
resource_type_added.emit(resource)
func consume_resource(resource: ResourceType, amount: int) -> bool:
if !stock.has(resource): return false
if stock[resource] == 0:
return false
stock[resource] -= amount
var failed = stock[resource] < 0
if failed:
stock[resource] = 0
return !failed
func add_resource(resource_type: ResourceType, amount: int):
ensure_resource(resource_type)
stock[resource_type] += amount
func get_resource_value(resource_type: ResourceType) -> int:
if !stock.has(resource_type): return 0
return stock[resource_type]
func get_resource_name(resource: ResourceType) -> String:
if resource in res_names: return res_names[resource]
return str(ResourceType.keys()[resource])
func get_resource_storage(resource: ResourceType):
if !storage.has(resource): return 0
return storage[resource]

View File

@ -0,0 +1 @@
uid://bv7oy4xlo7osf

View File

@ -0,0 +1,29 @@
extends PanelContainer
class_name ResourceTracker
@export var bar: ProgressBar
@export var name_label: Label
@export var value_label: Label
@export var changes: Label
@export var decreased_color: Color
@export var increased_color: Color
func set_increment(value: int):
changes.text = ("+ " + str(value)) if value > 0 \
else ("- " + str(abs(value))) if value < 0 \
else ("--")
var color = increased_color if value > 0 \
else decreased_color if value < 0 \
else Color.WHITE
if changes.label_settings == null: changes.label_settings = LabelSettings.new()
changes.label_settings.font_color = color
func set_resource_name(name: String):
name_label.text = name
func set_val_and_max(value: int, max: int):
value_label.text = str(value) + " / " + str(max)
bar.min_value = 0
bar.max_value = max if max != 0 else 1
bar.value = value

View File

@ -0,0 +1 @@
uid://cf3f8iyagxl08

View File

@ -0,0 +1,26 @@
extends VBoxContainer
var trackers: Dictionary[ResourceController.ResourceType, ResourceTracker] = {}
var resource_tracker_scene: PackedScene = preload("res://ResourceTracker.tscn")
func _ready():
var header = Label.new()
header.text = "Resources"
add_child(header)
for resource in ResourceController.stock.keys():
add_resource_ui(resource)
ResourceController.resource_type_added.connect(add_resource_ui)
ResourceController.resource_stats_updated.connect(_update_resource)
func _update_resource(resource_type: ResourceController.ResourceType, stats: ResourceController.ResourceStats):
if !trackers.has(resource_type): add_resource_ui(resource_type)
var tracker = trackers[resource_type]
tracker.set_val_and_max(stats.value, stats.max)
tracker.set_increment(stats.delta)
func add_resource_ui(resource_type: ResourceController.ResourceType):
var tracker: ResourceTracker = resource_tracker_scene.instantiate()
add_child(tracker)
tracker.set_resource_name(ResourceController.get_resource_name(resource_type))
trackers[resource_type] = tracker

View File

@ -0,0 +1 @@
uid://cg3qqaogq7h8q

View File

@ -1,11 +1,11 @@
extends Node2D
class_name SelectionManager
const SIGNAL_SELECTION_CHANGED = "selection-changed"
signal selection_updated
@export var selected_box_hidden_color = Color(1, 1, 1, 0)
@export var selected_box_color = Color(1, 1, 1, 0.6)
@onready var selection: Array[TileTransform] = []
@onready var selection: Array[Building] = []
var anim_t: float = 0.0
func _process(delta):
@ -16,19 +16,17 @@ func _process(delta):
func clear():
anim_t = 0
selection = []
emit_signal(SIGNAL_SELECTION_CHANGED)
print("clear selection ", len(selection))
selection_updated.emit(selection)
func append_array(items: Array[TileTransform]):
func append_array(items: Array[Building]):
selection.append_array(items)
emit_signal(SIGNAL_SELECTION_CHANGED)
selection_updated.emit(selection)
func select_array(items: Array[TileTransform]):
func select_array(items: Array[Building]):
clear()
if items.is_empty():
return
append_array(items)
print("selected ", len(selection))
func _draw():
if selection.is_empty():

View File

@ -1,47 +0,0 @@
@tool
extends Node2D
class_name TileRenderer
@export var base_color: Color = Color.SPRING_GREEN
@export var top_color: Color = Color.WEB_GREEN
var drawbox: Rect2
var drawbox_top: Rect2
var tile_transform: TileTransform
var grid: Grid
var text_pos: Vector2
func _ready():
tile_transform = Util.find_parent_type(self, TileTransform)
grid = Util.find_parent_type(self, Grid)
func _process(_delta):
queue_redraw()
func _draw():
_update_drawbox()
draw_rect(drawbox, base_color, true)
draw_rect(drawbox_top, top_color, true)
draw_string(ThemeDB.fallback_font, text_pos, "House", HORIZONTAL_ALIGNMENT_CENTER, drawbox_top.size.x, 12)
func _update_drawbox():
var size = self.tile_transform.size * (self.grid.cell_size if self.grid != null else 100)
var box = Rect2(size / -2.0, size)
if not is_node_ready():
return
self.drawbox = box
self.drawbox_top = Rect2(
drawbox.position.x + 2.0,
drawbox.position.y + drawbox.size.y - 18.0,
drawbox.size.x - 4.0,
16.0
)
# drawbox_top.size.y = 16
text_pos = drawbox_top.position
text_pos.y += drawbox_top.size.y - 3

View File

@ -1 +0,0 @@
uid://2mbjbn23ry8t

View File

@ -2,43 +2,26 @@
extends Node2D
class_name TileTransform
enum State {
CLEAN,
UPDATE_POSITION
# UPDATE_TILE_POS
}
@export var quantize_in_editor = true:
set(val):
quantize_in_editor = val
_quantize()
@export var size: Vector2i = Vector2i.ONE:
set(val):
size = val
_quantize()
# - - - - - - - - - - - - - - - -
update_world_from_tile()
queue_redraw()
@export var tile_pos: Vector2i = Vector2i.ZERO:
set(val):
tile_pos = val
update_world_from_tile()
queue_redraw()
var grid: Grid
var _worldbox: Rect2 = Rect2(0, 0, 0, 0)
var _tilebox: Rect2i = Rect2i(0, 0, 0, 0)
var state: State = State.CLEAN
var has_adjusted_positions_this_frame = false
func _ready():
if Engine.is_editor_hint(): set_notify_transform(true)
grid = Util.find_parent_type(self, Grid)
grid.register_tile(self)
set_notify_transform(true)
_quantize()
func _process(_delta):
has_adjusted_positions_this_frame = false
if state == State.UPDATE_POSITION:
_quantize()
update_world_from_tile()
func _enter_tree():
set_notify_transform(true)
if Engine.is_editor_hint(): set_notify_transform(true)
func _exit_tree():
if grid != null:
@ -46,44 +29,19 @@ func _exit_tree():
func _notification(what: int) -> void:
if what == NOTIFICATION_TRANSFORM_CHANGED:
_quantize()
if Engine.is_editor_hint(): _editor_position_changed()
func _tile_pos_updated():
pass
func update_world_from_tile():
if grid == null: return
var worldbox = grid.tile2world_rect(Rect2i(tile_pos, size))
position = worldbox.get_center()
func _size_updated():
pass
func _position_updated():
pass
func _quantize():
if Engine.is_editor_hint() && !quantize_in_editor:
return
if grid == null:
return
if has_adjusted_positions_this_frame:
state = State.UPDATE_POSITION
return
func _editor_position_changed():
var top_left_world_pos = position - grid.tile2world_size(size - Vector2i.ONE) / 2
var tile_pos = grid.world2tile(top_left_world_pos)
_worldbox = grid.tile2world_rect(Rect2i(tile_pos, size))
position = _worldbox.get_center()
print("updated " + self.name + "'s world box to: " + str(self._worldbox))
state = State.CLEAN
has_adjusted_positions_this_frame = true
func _derive():
pass
func _update_boxes():
pass
# func set_tile_pos(pos: Vector2i):
# pass
tile_pos = grid.world2tile(top_left_world_pos)
func get_worldbox():
return Rect2(_worldbox)
return grid.tile2world_rect(get_tilebox())
func get_tilebox():
return Rect2i(_tilebox)
return Rect2i(tile_pos, size)

View File

@ -1,20 +1,22 @@
@tool
extends Node
func find(type):
# probably move this to some sort of settings at some point
var animation_speed = 0.8
func find(type: Script):
var root = null
if Engine.is_editor_hint():
root = get_tree().edited_scene_root
else:
root = get_tree().root
return _find_type_on_base(root, type)
return find_child_type(root, type)
func find_parent_type(node: Node, type: Script):
var current_node = node
if node == null:
return null
#print("Searching for " + type.get_global_name() + " from " + node.name)
var i = 0
while current_node != null and i < 10:
@ -24,11 +26,11 @@ func find_parent_type(node: Node, type: Script):
current_node = current_node.get_parent()
return null;
func _find_type_on_base(base: Node, type):
func find_child_type(base: Node, type: Script):
if is_instance_of(base, type):
return base
for child in base.get_children():
var found_node = _find_type_on_base(child, type)
var found_node = find_child_type(child, type)
if found_node != null:
return found_node
return null

48
SelectionUI.gd 100644
View File

@ -0,0 +1,48 @@
extends VBoxContainer
@export var selection_manager: SelectionManager
@export var name_label: Label
@export var selection_panel: Control
@export var content_panel: Container
var grid: Grid
func _ready():
selection_manager.selection_updated.connect(_selection_updated)
grid = Util.find(Grid)
func deselect():
name_label.text = "Nothing Selected"
if !selection_panel.hidden: selection_panel.hide()
for child in content_panel.get_children(): child.queue_free()
func select_single(item: Building):
name_label.text = item.data.tile_name
selection_panel.show()
for child in content_panel.get_children(): child.queue_free()
for upgrade in item.data.upgrade_paths:
var container = FoldableContainer.new()
container.folded = false
container.title = upgrade.tile_name
content_panel.add_child(container)
for thing in upgrade.field_requirements:
match thing.get_script():
FieldMin:
var req = thing as FieldMin
var checkbox = CheckBox.new()
checkbox.text = str(Grid.Field.keys()[req.field])
checkbox.button_pressed = req.is_satisfied_at_position(grid, item.tile_pos)
checkbox.disabled = true
container.add_child(checkbox)
FieldMax:
var req = thing as FieldMax
var checkbox = CheckBox.new()
checkbox.text = str(Grid.Field.keys()[req.field])
checkbox.button_pressed = req.is_satisfied_at_position(grid, item.tile_pos)
checkbox.disabled = true
container.add_child(checkbox)
func _selection_updated(things: Array[Building]):
if things.size() == 0: deselect()
if things.size() == 1: select_single(things[0])

View File

@ -0,0 +1 @@
uid://ngiejslhl66p

View File

@ -0,0 +1,28 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=8 format=3 uid="uid://doqny7m7x1jnl"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_gaxmn"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_wkv8k"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_jwb6i"]
[ext_resource type="Script" uid="uid://5h2g03dsx026" path="res://ResourceScripts/FieldRequirements/FieldMax.gd" id="3_wkv8k"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_ig22d"]
[sub_resource type="Resource" id="Resource_xr6hc"]
script = ExtResource("1_gaxmn")
field = 4
range = 2.4
falloff = 1
metadata/_custom_type_script = "uid://cggmew2iau84h"
[sub_resource type="Resource" id="Resource_jwb6i"]
script = ExtResource("3_wkv8k")
field = 4
metadata/_custom_type_script = "uid://5h2g03dsx026"
[resource]
script = ExtResource("4_ig22d")
tile_name = "Forest"
style = 3
color = Color(0.11764706, 0.45882353, 0.19215687, 1)
field_requirements = Array[ExtResource("2_wkv8k")]([SubResource("Resource_jwb6i")])
field_emissions = Array[ExtResource("1_gaxmn")]([SubResource("Resource_xr6hc")])
metadata/_custom_type_script = "uid://y688w7tmv2dr"

View File

@ -0,0 +1,15 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=6 format=3 uid="uid://c2ajd2c6fu04d"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_sgs2a"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_kjhvl"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_d636l"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_rxh8u"]
[ext_resource type="Resource" uid="uid://bpi8ngu73jg15" path="res://Tiles/Farm/Wild Field.tres" id="5_kjhvl"]
[resource]
script = ExtResource("4_rxh8u")
tile_name = "Farmland"
style = 2
color = Color(0.182, 0.7, 0.29423332, 1)
upgrade_paths = Array[ExtResource("4_rxh8u")]([ExtResource("5_kjhvl")])
metadata/_custom_type_script = "uid://y688w7tmv2dr"

View File

@ -0,0 +1,37 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=9 format=3 uid="uid://bpi8ngu73jg15"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_xr6hc"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_vby5q"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_2of5e"]
[ext_resource type="Script" uid="uid://5h2g03dsx026" path="res://ResourceScripts/FieldRequirements/FieldMax.gd" id="3_hfx08"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_hfx08"]
[sub_resource type="Resource" id="Resource_xr6hc"]
script = ExtResource("1_xr6hc")
field = 3
amount = 1
range = 2.4
falloff = 1
metadata/_custom_type_script = "uid://cggmew2iau84h"
[sub_resource type="Resource" id="Resource_vby5q"]
script = ExtResource("1_xr6hc")
field = 4
amount = 1
range = 3.4
falloff = 1
metadata/_custom_type_script = "uid://cggmew2iau84h"
[sub_resource type="Resource" id="Resource_yitr5"]
script = ExtResource("3_hfx08")
field = 1
metadata/_custom_type_script = "uid://5h2g03dsx026"
[resource]
script = ExtResource("4_hfx08")
tile_name = "Wild Field"
style = 1
color = Color(0.11764706, 0.45882353, 0.19215687, 1)
field_requirements = Array[ExtResource("2_vby5q")]([SubResource("Resource_yitr5")])
field_emissions = Array[ExtResource("1_xr6hc")]([SubResource("Resource_xr6hc"), SubResource("Resource_vby5q")])
metadata/_custom_type_script = "uid://y688w7tmv2dr"

View File

@ -0,0 +1,15 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=7 format=3 uid="uid://bydddpqn0s43j"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_urkof"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_ad1a7"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_vifl3"]
[ext_resource type="Resource" uid="uid://bayaly21u33xj" path="res://Tiles/Housing/SmallLogCabin.tres" id="4_vifl3"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_y6hfj"]
[ext_resource type="Resource" uid="uid://ducxyya4a00oa" path="res://Tiles/Housing/Resting Spot.tres" id="6_ad1a7"]
[resource]
script = ExtResource("4_y6hfj")
tile_name = "Housing"
style = 2
color = Color(0.93333334, 0.39215687, 0.39215687, 1)
upgrade_paths = Array[ExtResource("4_y6hfj")]([ExtResource("4_vifl3"), ExtResource("6_ad1a7")])

View File

@ -0,0 +1,50 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=12 format=3 uid="uid://ducxyya4a00oa"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_ub44p"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_dege1"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_u7fxu"]
[ext_resource type="Script" uid="uid://5h2g03dsx026" path="res://ResourceScripts/FieldRequirements/FieldMax.gd" id="3_vev7e"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_vev7e"]
[ext_resource type="Resource" uid="uid://bayaly21u33xj" path="res://Tiles/Housing/SmallLogCabin.tres" id="5_2lp62"]
[sub_resource type="Resource" id="Resource_ub44p"]
script = ExtResource("1_ub44p")
field = 1
amount = 1
range = 6.0
falloff = 1
metadata/_custom_type_script = "uid://cggmew2iau84h"
[sub_resource type="Resource" id="Resource_2lp62"]
script = ExtResource("3_vev7e")
field = 1
metadata/_custom_type_script = "uid://5h2g03dsx026"
[sub_resource type="Resource" id="Resource_vev7e"]
script = ExtResource("3_u7fxu")
resource = 3
amount = 1
metadata/_custom_type_script = "uid://nroinmreopp4"
[sub_resource type="Resource" id="Resource_dege1"]
script = ExtResource("3_u7fxu")
resource = 1
amount = 1
metadata/_custom_type_script = "uid://nroinmreopp4"
[sub_resource type="Resource" id="Resource_u7fxu"]
script = ExtResource("3_u7fxu")
resource = 1
amount = 5
metadata/_custom_type_script = "uid://nroinmreopp4"
[resource]
script = ExtResource("4_vev7e")
tile_name = "Resting Spot"
color = Color(0.16799998, 0.6272, 0.84, 1)
field_requirements = Array[ExtResource("2_dege1")]([SubResource("Resource_2lp62")])
field_emissions = Array[ExtResource("1_ub44p")]([SubResource("Resource_ub44p")])
resource_consumption = Array[ExtResource("3_u7fxu")]([SubResource("Resource_vev7e")])
resource_prouction = Array[ExtResource("3_u7fxu")]([SubResource("Resource_dege1")])
resource_stockpiles = Array[ExtResource("3_u7fxu")]([SubResource("Resource_u7fxu")])
upgrade_paths = Array[ExtResource("4_vev7e")]([ExtResource("5_2lp62")])

View File

@ -0,0 +1,48 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=11 format=3 uid="uid://bayaly21u33xj"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_8x1k6"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_a3657"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_704a6"]
[ext_resource type="Script" uid="uid://b3ly4vy7xaynq" path="res://ResourceScripts/FieldRequirements/FieldMin.gd" id="3_o1qah"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_abho1"]
[sub_resource type="Resource" id="Resource_rmy5c"]
script = ExtResource("1_8x1k6")
field = 1
amount = 1
range = 3.4
falloff = 1
metadata/_custom_type_script = "uid://cggmew2iau84h"
[sub_resource type="Resource" id="Resource_m7mkw"]
script = ExtResource("3_o1qah")
min = 1
metadata/_custom_type_script = "uid://b3ly4vy7xaynq"
[sub_resource type="Resource" id="Resource_0amp2"]
script = ExtResource("3_704a6")
resource = 3
amount = 3
metadata/_custom_type_script = "uid://nroinmreopp4"
[sub_resource type="Resource" id="Resource_3d64m"]
script = ExtResource("3_704a6")
resource = 1
amount = 1
metadata/_custom_type_script = "uid://nroinmreopp4"
[sub_resource type="Resource" id="Resource_abho1"]
script = ExtResource("3_704a6")
amount = 60
metadata/_custom_type_script = "uid://nroinmreopp4"
[resource]
script = ExtResource("4_abho1")
tile_name = "Small Log Cabin"
color = Color(0.4117647, 0.22745098, 0.11764706, 1)
field_requirements = Array[ExtResource("2_a3657")]([SubResource("Resource_m7mkw")])
field_emissions = Array[ExtResource("1_8x1k6")]([SubResource("Resource_rmy5c")])
resource_requirements = Array[ExtResource("3_704a6")]([SubResource("Resource_abho1")])
resource_consumption = Array[ExtResource("3_704a6")]([SubResource("Resource_0amp2")])
resource_prouction = Array[ExtResource("3_704a6")]([SubResource("Resource_3d64m")])
metadata/_custom_type_script = "uid://y688w7tmv2dr"

View File

@ -0,0 +1,50 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=11 format=3 uid="uid://ctnjk4bt5mlps"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_3r0pf"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_8u1an"]
[ext_resource type="Script" uid="uid://b3ly4vy7xaynq" path="res://ResourceScripts/FieldRequirements/FieldMin.gd" id="3_v4xpb"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_vkbw8"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_v4xpb"]
[sub_resource type="Resource" id="Resource_3r0pf"]
script = ExtResource("1_3r0pf")
field = 3
amount = -4
range = 5.0
falloff = 1
metadata/_custom_type_script = "uid://cggmew2iau84h"
[sub_resource type="Resource" id="Resource_hi55i"]
script = ExtResource("3_v4xpb")
field = 3
min = 6
metadata/_custom_type_script = "uid://b3ly4vy7xaynq"
[sub_resource type="Resource" id="Resource_vkbw8"]
script = ExtResource("3_vkbw8")
resource = 1
amount = 1
metadata/_custom_type_script = "uid://nroinmreopp4"
[sub_resource type="Resource" id="Resource_v4xpb"]
script = ExtResource("3_vkbw8")
resource = 3
amount = 5
metadata/_custom_type_script = "uid://nroinmreopp4"
[sub_resource type="Resource" id="Resource_8fufg"]
script = ExtResource("3_vkbw8")
resource = 3
amount = 100
metadata/_custom_type_script = "uid://nroinmreopp4"
[resource]
script = ExtResource("4_v4xpb")
tile_name = "Foraging Camp"
color = Color(0.15294118, 0.42352942, 0.6627451, 1)
field_requirements = Array[ExtResource("2_8u1an")]([SubResource("Resource_hi55i")])
field_emissions = Array[ExtResource("1_3r0pf")]([SubResource("Resource_3r0pf")])
resource_consumption = Array[ExtResource("3_vkbw8")]([SubResource("Resource_vkbw8")])
resource_prouction = Array[ExtResource("3_vkbw8")]([SubResource("Resource_v4xpb")])
resource_stockpiles = Array[ExtResource("3_vkbw8")]([SubResource("Resource_8fufg")])
metadata/_custom_type_script = "uid://y688w7tmv2dr"

View File

@ -0,0 +1,16 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=7 format=3 uid="uid://bl6ps1ycelcxx"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_olh0m"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_olh0m"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_uba8x"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_ex0ko"]
[ext_resource type="Resource" uid="uid://behst2ge8nu8e" path="res://Tiles/Industry/Logging Camp.tres" id="5_adjmk"]
[ext_resource type="Resource" uid="uid://ctnjk4bt5mlps" path="res://Tiles/Industry/Foraging Camp.tres" id="6_lmdb6"]
[resource]
script = ExtResource("4_ex0ko")
tile_name = "Gathering Camp"
style = 2
color = Color(0.65, 0.57135, 0.43549997, 1)
upgrade_paths = Array[ExtResource("4_ex0ko")]([ExtResource("6_lmdb6"), ExtResource("5_adjmk")])
metadata/_custom_type_script = "uid://y688w7tmv2dr"

View File

@ -0,0 +1,50 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=11 format=3 uid="uid://behst2ge8nu8e"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_ln2xb"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_ln2xb"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_50uuq"]
[ext_resource type="Script" uid="uid://b3ly4vy7xaynq" path="res://ResourceScripts/FieldRequirements/FieldMin.gd" id="3_lrtjs"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_rgqp8"]
[sub_resource type="Resource" id="Resource_3r0pf"]
script = ExtResource("1_ln2xb")
field = 3
amount = -4
range = 4.9
falloff = 1
metadata/_custom_type_script = "uid://cggmew2iau84h"
[sub_resource type="Resource" id="Resource_50uuq"]
script = ExtResource("3_lrtjs")
field = 4
min = 10
metadata/_custom_type_script = "uid://b3ly4vy7xaynq"
[sub_resource type="Resource" id="Resource_vkbw8"]
script = ExtResource("3_50uuq")
resource = 1
amount = 1
metadata/_custom_type_script = "uid://nroinmreopp4"
[sub_resource type="Resource" id="Resource_v4xpb"]
script = ExtResource("3_50uuq")
resource = 3
amount = 10
metadata/_custom_type_script = "uid://nroinmreopp4"
[sub_resource type="Resource" id="Resource_8fufg"]
script = ExtResource("3_50uuq")
resource = 3
amount = 100
metadata/_custom_type_script = "uid://nroinmreopp4"
[resource]
script = ExtResource("4_rgqp8")
tile_name = "Gathering Camp"
color = Color(0.42, 0.19725999, 0.058799993, 1)
field_requirements = Array[ExtResource("2_ln2xb")]([SubResource("Resource_50uuq")])
field_emissions = Array[ExtResource("1_ln2xb")]([SubResource("Resource_3r0pf")])
resource_consumption = Array[ExtResource("3_50uuq")]([SubResource("Resource_vkbw8")])
resource_prouction = Array[ExtResource("3_50uuq")]([SubResource("Resource_v4xpb")])
resource_stockpiles = Array[ExtResource("3_50uuq")]([SubResource("Resource_8fufg")])
metadata/_custom_type_script = "uid://y688w7tmv2dr"

View File

@ -0,0 +1,28 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=7 format=3 uid="uid://djc16ouv6gmv1"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_g7euo"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_f70jb"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_0x3jy"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="4_hq0rs"]
[sub_resource type="Resource" id="Resource_bu2mc"]
script = ExtResource("1_g7euo")
amount = 1
range = 2.4
falloff = 1
metadata/_custom_type_script = "uid://cggmew2iau84h"
[sub_resource type="Resource" id="Resource_1q03n"]
script = ExtResource("3_0x3jy")
resource = 1
amount = 10
metadata/_custom_type_script = "uid://nroinmreopp4"
[resource]
script = ExtResource("4_hq0rs")
tile_name = "Cleared Path"
area_type = 1
style = 1
color = Color(1, 1, 1, 1)
field_emissions = Array[ExtResource("1_g7euo")]([SubResource("Resource_bu2mc")])
resource_requirements = Array[ExtResource("3_0x3jy")]([SubResource("Resource_1q03n")])

View File

@ -0,0 +1,15 @@
[gd_resource type="Resource" script_class="BuildingData" load_steps=6 format=3 uid="uid://b4jvgwx5i6785"]
[ext_resource type="Script" uid="uid://cggmew2iau84h" path="res://ResourceScripts/FieldEmission.gd" id="1_bu2mc"]
[ext_resource type="Script" uid="uid://y688w7tmv2dr" path="res://ResourceScripts/BuildingData.gd" id="1_mip7k"]
[ext_resource type="Script" uid="uid://c2winf4nct0u7" path="res://ResourceScripts/FieldRequirements/FieldRequirement.gd" id="2_gmo0p"]
[ext_resource type="Script" uid="uid://nroinmreopp4" path="res://ResourceScripts/ResourceAmount.gd" id="3_g11go"]
[ext_resource type="Resource" uid="uid://djc16ouv6gmv1" path="res://Tiles/Road/Cleared Path.tres" id="5_r5pii"]
[resource]
script = ExtResource("1_mip7k")
tile_name = "Path"
area_type = 1
style = 2
color = Color(1, 1, 1, 1)
upgrade_paths = Array[ExtResource("1_mip7k")]([ExtResource("5_r5pii")])

View File

@ -1,12 +0,0 @@
[gd_scene load_steps=3 format=3 uid="uid://cgygrdlj7ty6s"]
[ext_resource type="Script" uid="uid://cqhn1h452g2li" path="res://Scripts/TileTransform.gd" id="1_jjdrc"]
[ext_resource type="Script" uid="uid://2mbjbn23ry8t" path="res://Scripts/TileRenderer.gd" id="2_p4boj"]
[node name="Farm" type="Node2D"]
script = ExtResource("1_jjdrc")
[node name="TileRenderer" type="Node2D" parent="."]
script = ExtResource("2_p4boj")
base_color = Color(0.0828, 0.36, 0.13362, 1)
top_color = Color(0.0108, 0.18, 0.04182, 1)

View File

@ -1,9 +1,22 @@
[gd_scene load_steps=5 format=3 uid="uid://co6md8v2b8hhu"]
[gd_scene load_steps=18 format=3 uid="uid://co6md8v2b8hhu"]
[ext_resource type="Script" uid="uid://8lkq20gwkrvx" path="res://Scripts/Grid.gd" id="1_2s04l"]
[ext_resource type="Script" uid="uid://cuqcfju7y8ply" path="res://Scripts/SelectionManager.gd" id="1_anesy"]
[ext_resource type="PackedScene" uid="uid://cgygrdlj7ty6s" path="res://Tiles/farm.tscn" id="2_7ixwv"]
[ext_resource type="Script" uid="uid://xe60g0el2j5x" path="res://Scripts/GridInput.gd" id="3_62nr3"]
[ext_resource type="Script" uid="uid://du3m15i8ahlu5" path="res://Scripts/CursorPool.gd" id="3_fvag4"]
[ext_resource type="Script" uid="uid://j6fc2qc5t3qa" path="res://Scripts/FPSCounter.gd" id="5_eu7l1"]
[ext_resource type="Theme" uid="uid://dks3mt6h14i2s" path="res://Gradients/DefaultTheme.tres" id="6_bah7m"]
[ext_resource type="Script" uid="uid://d1lhn37ijatdp" path="res://Scripts/BuildMenu.gd" id="6_wygdx"]
[ext_resource type="Script" uid="uid://p8y4cfg2aonj" path="res://Scripts/BuildButton.gd" id="7_bah7m"]
[ext_resource type="Resource" uid="uid://bydddpqn0s43j" path="res://Tiles/Housing/Housing.tres" id="9_fvag4"]
[ext_resource type="Resource" uid="uid://c2ajd2c6fu04d" path="res://Tiles/Farm/Reservation.tres" id="10_b2ar6"]
[ext_resource type="Resource" uid="uid://b4jvgwx5i6785" path="res://Tiles/Road/Path.tres" id="10_kva58"]
[ext_resource type="Resource" uid="uid://bl6ps1ycelcxx" path="res://Tiles/Industry/Gathering Camp.tres" id="11_ee7l0"]
[ext_resource type="Script" uid="uid://cj8bj60oyrc4f" path="res://Scripts/DebugMenu.gd" id="11_kva58"]
[ext_resource type="Script" uid="uid://cg3qqaogq7h8q" path="res://Scripts/ResourcesPanel.gd" id="12_f5c0m"]
[ext_resource type="Script" uid="uid://ngiejslhl66p" path="res://SelectionUI.gd" id="13_1fphk"]
[ext_resource type="Script" uid="uid://rr8s2u7xswtc" path="res://Scripts/Calendar.gd" id="13_6w02q"]
[ext_resource type="Theme" uid="uid://s3apw670qymv" path="res://Gradients/ResourcesTheme.tres" id="15_gn8l5"]
[node name="Root" type="Node2D"]
@ -11,25 +24,176 @@
[node name="Grid" type="Node2D" parent="."]
script = ExtResource("1_2s04l")
cells = 10
cells = 15
cell_size = 48
grid_color = Color(0.6627451, 0.7764706, 0.5647059, 1)
line_color = Color(1, 1, 1, 0)
debug_overlay_enabled = false
debug_overlay_display_values = null
[node name="Tiles" type="Node" parent="Grid"]
[node name="Farm" parent="Grid" instance=ExtResource("2_7ixwv")]
position = Vector2(-96, 192)
size = Vector2i(6, 2)
[node name="Farm2" parent="Grid" instance=ExtResource("2_7ixwv")]
position = Vector2(-144, -120)
size = Vector2i(2, 3)
[node name="Farm3" parent="Grid" instance=ExtResource("2_7ixwv")]
position = Vector2(168, -72)
[node name="GridInput" type="Node2D" parent="."]
[node name="GridInput" type="Node2D" parent="." node_paths=PackedStringArray("selection_manager")]
script = ExtResource("3_62nr3")
highlight_color = Color(1, 1, 1, 0.301961)
selection_manager = NodePath("../SelectionManager")
[node name="CursorPool" type="Node2D" parent="GridInput"]
script = ExtResource("3_fvag4")
[node name="SelectionManager" type="Node2D" parent="."]
script = ExtResource("1_anesy")
[node name="CanvasLayer" type="CanvasLayer" parent="."]
[node name="Left Panel" type="Panel" parent="CanvasLayer"]
anchors_preset = 9
anchor_bottom = 1.0
offset_right = 300.0
theme = ExtResource("6_bah7m")
[node name="TabContainer" type="TabContainer" parent="CanvasLayer/Left Panel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
current_tab = 1
[node name="Build" type="TabBar" parent="CanvasLayer/Left Panel/TabContainer"]
visible = false
layout_mode = 2
metadata/_tab_index = 0
[node name="VBox" type="VBoxContainer" parent="CanvasLayer/Left Panel/TabContainer/Build" node_paths=PackedStringArray("grid_input", "grid")]
layout_mode = 0
offset_right = 280.0
offset_bottom = 826.0
script = ExtResource("6_wygdx")
grid_input = NodePath("../../../../../GridInput")
grid = NodePath("../../../../../Grid")
[node name="Label" type="Label" parent="CanvasLayer/Left Panel/TabContainer/Build/VBox"]
layout_mode = 2
text = "Zoning"
[node name="Build Road" type="Button" parent="CanvasLayer/Left Panel/TabContainer/Build/VBox"]
layout_mode = 2
text = "Road"
script = ExtResource("7_bah7m")
building = ExtResource("10_kva58")
[node name="Build House" type="Button" parent="CanvasLayer/Left Panel/TabContainer/Build/VBox"]
layout_mode = 2
text = "Housing"
script = ExtResource("7_bah7m")
building = ExtResource("9_fvag4")
[node name="Farmland" type="Button" parent="CanvasLayer/Left Panel/TabContainer/Build/VBox"]
layout_mode = 2
text = "Housing"
script = ExtResource("7_bah7m")
building = ExtResource("10_b2ar6")
[node name="Foraging Camp" type="Button" parent="CanvasLayer/Left Panel/TabContainer/Build/VBox"]
layout_mode = 2
text = "Housing"
script = ExtResource("7_bah7m")
building = ExtResource("11_ee7l0")
[node name="Debug" type="TabBar" parent="CanvasLayer/Left Panel/TabContainer"]
layout_mode = 2
metadata/_tab_index = 1
[node name="Overlay Controller" type="VBoxContainer" parent="CanvasLayer/Left Panel/TabContainer/Debug" node_paths=PackedStringArray("grid", "overlay_enabled_button", "overlay_selection_button", "overlay_display_values")]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("11_kva58")
grid = NodePath("../../../../../Grid")
overlay_enabled_button = NodePath("Enable")
overlay_selection_button = NodePath("Select Field")
overlay_display_values = NodePath("Display Values")
[node name="Enable" type="CheckButton" parent="CanvasLayer/Left Panel/TabContainer/Debug/Overlay Controller"]
layout_mode = 2
text = "Field Overlay"
[node name="Display Values" type="CheckButton" parent="CanvasLayer/Left Panel/TabContainer/Debug/Overlay Controller"]
layout_mode = 2
text = "Display Values"
[node name="Select Field" type="OptionButton" parent="CanvasLayer/Left Panel/TabContainer/Debug/Overlay Controller"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Selection" type="TabBar" parent="CanvasLayer/Left Panel/TabContainer"]
visible = false
layout_mode = 2
metadata/_tab_index = 2
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Left Panel/TabContainer/Selection" node_paths=PackedStringArray("selection_manager", "name_label", "selection_panel", "content_panel")]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("13_1fphk")
selection_manager = NodePath("../../../../../SelectionManager")
name_label = NodePath("Label")
selection_panel = NodePath("..")
content_panel = NodePath("VBoxContainer")
[node name="Label" type="Label" parent="CanvasLayer/Left Panel/TabContainer/Selection/VBoxContainer"]
layout_mode = 2
text = "Selected Item Name"
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Left Panel/TabContainer/Selection/VBoxContainer"]
layout_mode = 2
[node name="Right Panel" type="Panel" parent="CanvasLayer"]
anchors_preset = 11
anchor_left = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -273.0
grow_horizontal = 0
grow_vertical = 2
theme = ExtResource("6_bah7m")
[node name="MarginContainer" type="MarginContainer" parent="CanvasLayer/Right Panel"]
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="CanvasLayer/Right Panel/MarginContainer"]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="CanvasLayer/Right Panel/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="Calendar" type="Label" parent="CanvasLayer/Right Panel/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
text = "Calendar"
script = ExtResource("13_6w02q")
[node name="FPS" type="Label" parent="CanvasLayer/Right Panel/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_vertical = 1
text = "FPS: 9999"
script = ExtResource("5_eu7l1")
[node name="HSeparator" type="HSeparator" parent="CanvasLayer/Right Panel/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="Resource Panels" type="VBoxContainer" parent="CanvasLayer/Right Panel/MarginContainer/VBoxContainer"]
layout_mode = 2
theme = ExtResource("15_gn8l5")
script = ExtResource("12_f5c0m")

View File

@ -0,0 +1,19 @@
extends EditorInspectorPlugin
func _can_handle(object):
return object is BuildingData
func _parse_begin(object):
# Example: Add a label at the top
var label = Label.new()
label.text = "Custom Editor for MyData!"
add_custom_control(label)
return true
func _parse_property(object, type, path, hint, hint_text, usage, wide):
return true
func _parse_group(object, name):
return false
func _parse_category(object, name):
return true

View File

@ -0,0 +1,10 @@
@tool
extends EditorPlugin
var inspector = preload("res://addons/CustomEditors/BuildingDataHelper.gd").new()
func _enter_tree():
add_inspector_plugin(inspector)
func _exit_tree():
remove_inspector_plugin(inspector)

View File

@ -0,0 +1 @@
uid://uuouru33qiot

View File

@ -0,0 +1,7 @@
[plugin]
name="Custom Editors"
description=""
author="Valerie"
version="1.0"
script="CustomEditors.gd"

View File

@ -1,13 +0,0 @@
@tool
extends EditorPlugin
func _handles(object):
return object is Tile
func _enter_tree():
# Initialization of the plugin goes here.
pass
func _exit_tree():
# Clean-up of the plugin goes here.
pass

View File

@ -1,7 +0,0 @@
[plugin]
name="Tile Helper"
description=""
author=""
version=""
script="TileHelper.gd"

42
export_presets.cfg 100644
View File

@ -0,0 +1,42 @@
[preset.0]
name="Linux"
platform="Linux"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../../../Downloads/CityGame.x86_64"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
shader_baker/enabled=false
binary_format/architecture="x86_64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash
export DISPLAY=:0
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
\"{temp_dir}/{exe_name}\" {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""

View File

@ -1 +0,0 @@
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 813 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H447l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c3 34 55 34 58 0v-86c-3-34-55-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 950 B

View File

@ -1,37 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://txyjconsf31o"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -12,23 +12,24 @@ config_version=5
config/name="MobileGame"
run/main_scene="res://World.tscn"
config/features=PackedStringArray("4.4", "Mobile")
config/icon="res://icon.svg"
config/features=PackedStringArray("4.5", "Mobile")
[autoload]
Util="*res://Scripts/Util.gd"
ResourceController="*res://Scripts/ResourceController.gd"
Clock="*res://Scripts/Clock.gd"
[display]
window/size/viewport_width=1600
window/size/viewport_height=900
window/vsync/vsync_mode=0
[editor_plugins]
[gui]
enabled=PackedStringArray()
theme/default_font_multichannel_signed_distance_field=true
[rendering]
renderer/rendering_method="mobile"
environment/defaults/default_clear_color=Color(0, 0, 0, 1)
environment/defaults/default_clear_color=Color(0.8745098, 0.8745098, 0.8745098, 1)