Pre-submission
|
@ -1 +1,2 @@
|
|||
.import
|
||||
*.import
|
||||
build/
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
extends Node2D
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
var rings = 4
|
||||
var storage = []
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func init_storage(rings: int):
|
||||
self.rings = rings
|
||||
self.storage = []
|
||||
# Not the smallest size, but will make a "square" buffer and some
|
||||
# indices will never be accessed by get_item()
|
||||
var size = (rings * 2) - 1
|
||||
size *= size
|
||||
self.storage.resize(size)
|
||||
|
||||
func _get_index(q: int, r: int):
|
||||
# Using axial coordinates q and r are bounded from -(rings-1) to (rings-1)
|
||||
assert(_is_valid_q_r(q, r))
|
||||
# To map to storage, we "push" the values up by (rings-1) so there are
|
||||
# never any negative indices. Once there, we can use q, r as row, column
|
||||
# addresses
|
||||
var q_mod = q + (self.rings - 1)
|
||||
var r_mod = r + (self.rings - 1)
|
||||
var row_size = (self.rings * 2) - 1
|
||||
var index = (q_mod * row_size) + r_mod
|
||||
assert(index < self.storage.size())
|
||||
return index
|
||||
|
||||
func _is_valid_q_r(q: int, r: int):
|
||||
return abs(q) < self.rings and abs(r) < self.rings
|
||||
|
||||
func get_item(q: int, r: int):
|
||||
var index = self._get_index(q, r)
|
||||
return self.storage[index]
|
||||
|
||||
func set_item(q: int, r: int, item):
|
||||
var index = _get_index(q, r)
|
||||
self.storage[index] = item
|
||||
|
||||
func tag_edge_nodes(direction: Vector2, group: String):
|
||||
var edges = []
|
||||
for item in self.storage:
|
||||
if item == null:
|
||||
continue
|
||||
var loc = item.pf_location
|
||||
var adjacent_spot = loc + direction
|
||||
#print("Testing location: ", loc)
|
||||
if not self._is_valid_q_r(adjacent_spot.x, adjacent_spot.y):
|
||||
edges.append(loc)
|
||||
continue
|
||||
var neighbour = self.get_item(adjacent_spot.x, adjacent_spot.y)
|
||||
if neighbour == null:
|
||||
edges.append(loc)
|
||||
for e in edges:
|
||||
var item = self.get_item(e.x, e.y)
|
||||
item.add_to_group(group)
|
||||
|
||||
func get_neighbours(q, r):
|
||||
return []
|
|
@ -0,0 +1,46 @@
|
|||
extends PopupPanel
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
|
||||
|
||||
func _on_Continue_pressed():
|
||||
self.set_visible(false)
|
||||
|
||||
func _on_Quit_pressed():
|
||||
get_tree().quit()
|
||||
|
||||
func _on_Help_pressed():
|
||||
self.set_visible(false)
|
||||
# Brittle, refers to the layout in "Game" scenetree
|
||||
get_node("../Help").set_visible(true)
|
||||
|
||||
|
||||
func _on_Restart_pressed():
|
||||
get_tree().get_root().get_node("/root/Game").reset()
|
||||
self.set_visible(false)
|
||||
|
||||
func _on_scores_updated(scores):
|
||||
var total = 0
|
||||
var max_score = 0
|
||||
for x in scores:
|
||||
total += x
|
||||
max_score = max(max_score, x)
|
||||
get_node("VBoxContainer/Score").set_bbcode("[center]Score: %d[/center]" % total)
|
||||
var s = ""
|
||||
for x in range(scores.size()):
|
||||
s += "Year %d: %d\n" % [x, scores[x]]
|
||||
print(s)
|
||||
get_node("VBoxContainer/ScoreByYear").set_bbcode(s)
|
20
README.md
|
@ -0,0 +1,20 @@
|
|||
# LD54 : Da 'lil Patch
|
||||
|
||||
You only have a small space. Can you keep it cultivated and producing well as
|
||||
the years go on?
|
||||
|
||||
## Tools
|
||||
|
||||
* Debian Linux
|
||||
* Godot 3.5 (gdscript)
|
||||
* Art: GIMP, mypaint, inkscape, krita
|
||||
* Sound: Audacity
|
||||
|
||||
## External Assets
|
||||
|
||||
* Font: Bitstream Vera Mono Nerd
|
||||
|
||||
## Licenses
|
||||
|
||||
* Assets (excluding font): CC-BY-SA-4.0
|
||||
* Source code: GPLv3
|
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 581 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 210 297"
|
||||
version="1.1"
|
||||
id="svg135"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="hex.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview137"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.9897026"
|
||||
inkscape:cx="198.34749"
|
||||
inkscape:cy="216.74397"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs132" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.352999;stroke-linejoin:bevel;paint-order:markers fill stroke"
|
||||
id="path576"
|
||||
inkscape:flatsided="true"
|
||||
sodipodi:sides="6"
|
||||
sodipodi:cx="47.286068"
|
||||
sodipodi:cy="53.504932"
|
||||
sodipodi:r1="22.602188"
|
||||
sodipodi:r2="19.574068"
|
||||
sodipodi:arg1="0.52369612"
|
||||
sodipodi:arg2="1.0472949"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="M 66.859037,64.807932 47.283868,76.10712 27.710899,64.804121 l 0.0022,-22.602188 19.575169,-11.299189 19.572969,11.303 z" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 5.6 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 5.4 KiB |
|
@ -0,0 +1,176 @@
|
|||
[preset.0]
|
||||
|
||||
name="Linux/X11"
|
||||
platform="Linux/X11"
|
||||
runnable=true
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="build/linux-x86_64/dalilpatch.x86_64"
|
||||
script_export_mode=1
|
||||
script_encryption_key=""
|
||||
|
||||
[preset.0.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
binary_format/64_bits=true
|
||||
binary_format/embed_pck=false
|
||||
texture_format/bptc=false
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
texture_format/no_bptc_fallbacks=true
|
||||
|
||||
[preset.1]
|
||||
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=true
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="build/win11-x64_64/dalilpatch.x86_64.exe"
|
||||
script_export_mode=1
|
||||
script_encryption_key=""
|
||||
|
||||
[preset.1.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
binary_format/64_bits=true
|
||||
binary_format/embed_pck=false
|
||||
texture_format/bptc=false
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
texture_format/no_bptc_fallbacks=true
|
||||
codesign/enable=false
|
||||
codesign/identity_type=0
|
||||
codesign/identity=""
|
||||
codesign/password=""
|
||||
codesign/timestamp=true
|
||||
codesign/timestamp_server_url=""
|
||||
codesign/digest_algorithm=1
|
||||
codesign/description=""
|
||||
codesign/custom_options=PoolStringArray( )
|
||||
application/modify_resources=true
|
||||
application/icon=""
|
||||
application/file_version=""
|
||||
application/product_version=""
|
||||
application/company_name=""
|
||||
application/product_name=""
|
||||
application/file_description=""
|
||||
application/copyright=""
|
||||
application/trademarks=""
|
||||
|
||||
[preset.2]
|
||||
|
||||
name="HTML5"
|
||||
platform="HTML5"
|
||||
runnable=true
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="build/web/dalilpatch.x86_64.exe.html"
|
||||
script_export_mode=1
|
||||
script_encryption_key=""
|
||||
|
||||
[preset.2.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
variant/export_type=0
|
||||
vram_texture_compression/for_desktop=true
|
||||
vram_texture_compression/for_mobile=false
|
||||
html/export_icon=true
|
||||
html/custom_html_shell=""
|
||||
html/head_include=""
|
||||
html/canvas_resize_policy=2
|
||||
html/focus_canvas_on_start=true
|
||||
html/experimental_virtual_keyboard=false
|
||||
progressive_web_app/enabled=false
|
||||
progressive_web_app/offline_page=""
|
||||
progressive_web_app/display=1
|
||||
progressive_web_app/orientation=0
|
||||
progressive_web_app/icon_144x144=""
|
||||
progressive_web_app/icon_180x180=""
|
||||
progressive_web_app/icon_512x512=""
|
||||
progressive_web_app/background_color=Color( 0, 0, 0, 1 )
|
||||
|
||||
[preset.3]
|
||||
|
||||
name="Mac OSX"
|
||||
platform="Mac OSX"
|
||||
runnable=true
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="build/osx/dalilpatch.x86_64.exe.html.zip"
|
||||
script_export_mode=1
|
||||
script_encryption_key=""
|
||||
|
||||
[preset.3.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
application/name=""
|
||||
application/info="Made with Godot Engine"
|
||||
application/icon=""
|
||||
application/identifier=""
|
||||
application/signature=""
|
||||
application/app_category="Games"
|
||||
application/short_version="1.0"
|
||||
application/version="1.0"
|
||||
application/copyright=""
|
||||
display/high_res=false
|
||||
privacy/microphone_usage_description=""
|
||||
privacy/camera_usage_description=""
|
||||
privacy/location_usage_description=""
|
||||
privacy/address_book_usage_description=""
|
||||
privacy/calendar_usage_description=""
|
||||
privacy/photos_library_usage_description=""
|
||||
privacy/desktop_folder_usage_description=""
|
||||
privacy/documents_folder_usage_description=""
|
||||
privacy/downloads_folder_usage_description=""
|
||||
privacy/network_volumes_usage_description=""
|
||||
privacy/removable_volumes_usage_description=""
|
||||
codesign/enable=true
|
||||
codesign/identity=""
|
||||
codesign/timestamp=true
|
||||
codesign/hardened_runtime=true
|
||||
codesign/replace_existing_signature=true
|
||||
codesign/entitlements/custom_file=""
|
||||
codesign/entitlements/allow_jit_code_execution=false
|
||||
codesign/entitlements/allow_unsigned_executable_memory=false
|
||||
codesign/entitlements/allow_dyld_environment_variables=false
|
||||
codesign/entitlements/disable_library_validation=false
|
||||
codesign/entitlements/audio_input=false
|
||||
codesign/entitlements/camera=false
|
||||
codesign/entitlements/location=false
|
||||
codesign/entitlements/address_book=false
|
||||
codesign/entitlements/calendars=false
|
||||
codesign/entitlements/photos_library=false
|
||||
codesign/entitlements/apple_events=false
|
||||
codesign/entitlements/debugging=false
|
||||
codesign/entitlements/app_sandbox/enabled=false
|
||||
codesign/entitlements/app_sandbox/network_server=false
|
||||
codesign/entitlements/app_sandbox/network_client=false
|
||||
codesign/entitlements/app_sandbox/device_usb=false
|
||||
codesign/entitlements/app_sandbox/device_bluetooth=false
|
||||
codesign/entitlements/app_sandbox/files_downloads=0
|
||||
codesign/entitlements/app_sandbox/files_pictures=0
|
||||
codesign/entitlements/app_sandbox/files_music=0
|
||||
codesign/entitlements/app_sandbox/files_movies=0
|
||||
codesign/custom_options=PoolStringArray( )
|
||||
notarization/enable=false
|
||||
notarization/apple_id_name=""
|
||||
notarization/apple_id_password=""
|
||||
notarization/apple_team_id=""
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
|
@ -11,12 +11,53 @@ config_version=4
|
|||
[application]
|
||||
|
||||
config/name="Ld 54"
|
||||
config/description="Get the most out of the small bit of land that you can call yours"
|
||||
run/main_scene="res://src/Game.tscn"
|
||||
boot_splash/show_image=false
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[gui]
|
||||
|
||||
common/drop_mouse_on_gui_input_disabled=true
|
||||
|
||||
[input]
|
||||
|
||||
ui_help={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":true,"control":false,"meta":false,"command":false,"pressed":false,"scancode":47,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
ui_plant={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
ui_query={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
ui_cull={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
ui_burn={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
ui_removerock={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":71,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
ui_fertilize={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":72,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[physics]
|
||||
|
||||
common/enable_pause_aware_picking=true
|
||||
|
|
|
@ -0,0 +1,435 @@
|
|||
extends Node
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
signal day_time_changed(old, new)
|
||||
signal season_changed(old, new)
|
||||
signal year_changed(old, new)
|
||||
signal action_points_changed(old, new)
|
||||
signal scores_updated(new)
|
||||
|
||||
enum SEASON {SPRING, SUMMER_1, SUMMER_2, FALL}
|
||||
const season_text = ["Spring", "Early Summer", "Late Summer", "Autumn"]
|
||||
const season_light_mod = [1.0, 1.1, 1.2, 1.0]
|
||||
enum TIME {DAWN, MORNING, AFTERNOON, DUSK}
|
||||
const time_text = ["Dawn", "Morning", "Afternoon", "Dusk"]
|
||||
const time_light_strength = [20, 60, 80, 10]
|
||||
const time_light_from = [
|
||||
# q-r space
|
||||
Vector2(-1, 0),
|
||||
Vector2(0, -1),
|
||||
Vector2(1, -1),
|
||||
Vector2(1, 0)
|
||||
]
|
||||
const time_light_to = [
|
||||
# q-r space
|
||||
Vector2(1, 0),
|
||||
Vector2(0, 1),
|
||||
Vector2(-1, 1),
|
||||
Vector2(-1, 0)
|
||||
]
|
||||
|
||||
const StructureSpot = preload("Spot.tscn")
|
||||
const Soil = preload("Soil.tscn")
|
||||
const Plant = preload("Plant.tscn")
|
||||
const HexGrid = preload("HexGrid.tscn")
|
||||
const FadingText = preload("res://src/ui/FadingText.tscn")
|
||||
|
||||
const hex_scale = 1.5
|
||||
const hex_size = 32 * hex_scale
|
||||
const hex_width = hex_size * sqrt(3)
|
||||
const hex_height = 2 * hex_size
|
||||
|
||||
var year = 0
|
||||
var scores = []
|
||||
var current_season = SEASON.SPRING
|
||||
var current_time = TIME.DAWN
|
||||
var grid = null
|
||||
var action_points = 3
|
||||
var current_action = "plant"
|
||||
var last_action = "plant"
|
||||
var current_plant = "corn"
|
||||
var current_ap = 3
|
||||
var current_hex = null
|
||||
var hex_click_start = null
|
||||
var stage_timer = 0.0
|
||||
var stage_time = 2.0
|
||||
|
||||
var plant_types = {
|
||||
"corn": preload("res://src/plants/Corn.tscn").instance(),
|
||||
"bean": preload("res://src/plants/Bean.tscn").instance(),
|
||||
"apple": preload("res://src/plants/Apple.tscn").instance(),
|
||||
"clover": preload("res://src/plants/Clover.tscn").instance(),
|
||||
"weed": preload("res://src/plants/Weed.tscn").instance(),
|
||||
"strong_weed": preload("res://src/plants/StrongWeed.tscn").instance(),
|
||||
}
|
||||
|
||||
func sun_strength(time, season):
|
||||
return round(self.time_light_strength[time] * self.season_light_mod[season])
|
||||
|
||||
func update_action_points(value):
|
||||
emit_signal("action_points_changed", self.action_points, self.action_points + value)
|
||||
self.action_points += value
|
||||
|
||||
func reset():
|
||||
get_tree().call_group("runtime", "queue_free")
|
||||
self.year = 0
|
||||
self.scores = [0]
|
||||
self.action_points = 3
|
||||
self.update_action_points(0)
|
||||
self.current_season = SEASON.SPRING
|
||||
self.current_time = TIME.DAWN
|
||||
self.current_ap = 3
|
||||
self.current_hex = null
|
||||
if self.current_action == "pass_time":
|
||||
self.current_action = self.last_action
|
||||
get_node("Ui/Right/VBoxContainer2/ActionMenu").unlock()
|
||||
self.hex_click_start = null
|
||||
self.stage_timer = -1.0
|
||||
self.grid = null
|
||||
print("Reset")
|
||||
self.init_playfield()
|
||||
|
||||
func init_playfield():
|
||||
var grid = HexGrid.instance()
|
||||
grid.add_to_group("runtime")
|
||||
grid.init_storage(4)
|
||||
var center = get_viewport().get_visible_rect().size / 2
|
||||
var hex_offset = Vector2(
|
||||
0, # ((4*2)-1) * hex_width / 2,
|
||||
((4*2)-1) * hex_height / 2
|
||||
)
|
||||
hex_offset.x += center.x
|
||||
# print(str(center))
|
||||
var soil = 0
|
||||
var spot = 0
|
||||
for q in range(-3, 4):
|
||||
for r in range(-3, 4):
|
||||
var s = -q-r
|
||||
# We don't want some parts of the rhombus on the playfield
|
||||
if abs((q + r)) >= 4:
|
||||
continue
|
||||
var x = null
|
||||
var pos = Vector2(0, 0)
|
||||
if abs(q) < 3 and abs(r) < 3 and abs(s) < 3:
|
||||
# On the inside make Soil
|
||||
x = Soil.instance()
|
||||
soil += 1
|
||||
else:
|
||||
# disable structure spots for the moment
|
||||
continue
|
||||
# On the outer ring, make a structure spot, except on the
|
||||
# bottom half
|
||||
if r >= 0:
|
||||
continue
|
||||
x = StructureSpot.instance()
|
||||
spot += 1
|
||||
x.add_to_group("runtime")
|
||||
x.set_location(Vector2(q, r))
|
||||
grid.set_item(q, r, x)
|
||||
# print("Created at ", q, ",", r, ": ", x)
|
||||
# Set position
|
||||
pos.y = hex_offset.y + (r * hex_height * 0.75)
|
||||
pos.x = hex_offset.x + (q * hex_width) + (r * (hex_size-5))
|
||||
#print(str(q), ",", str(r), " ", str(pos))
|
||||
x.set_position(pos)
|
||||
x.connect("mouse_entered", self, "_on_HexHover", [x, true])
|
||||
x.connect("mouse_exited", self, "_on_HexHover", [x, false])
|
||||
x.connect("input_event", self, "_on_HexInputEvent", [x])
|
||||
add_child(x)
|
||||
for t in range(self.time_light_from.size()):
|
||||
grid.tag_edge_nodes(self.time_light_from[t], "edge_time_%d" % t)
|
||||
#print("Created %d soil and %d spot tiles" % [soil, spot])
|
||||
self.grid = grid
|
||||
add_child(grid)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
find_node("PlantMenu").set_plants(self.plant_types)
|
||||
get_node("Ui/Right/VBoxContainer2/ActionMenu").connect("action_changed", self, "_on_action_changed")
|
||||
self.connect("action_points_changed", get_node("Ui/Right/VBoxContainer2/ActionMenu"), "_on_action_points_changed")
|
||||
get_node("Ui/Left/VBoxContainer/PlantMenu").connect("plant_type_changed", self, "_on_plant_type_changed")
|
||||
self.connect("action_points_changed", self, "_on_action_points_changed")
|
||||
self.connect("day_time_changed", get_node("Sun"), "_on_day_time_changed")
|
||||
self.connect("day_time_changed", self, "_on_day_time_changed")
|
||||
self.connect("season_changed", self, "_on_season_changed")
|
||||
self.connect("year_changed", self, "_on_year_changed")
|
||||
self.connect("scores_updated", get_node("Ui/Menu"), "_on_scores_updated")
|
||||
self.reset()
|
||||
randomize()
|
||||
|
||||
func advance_year():
|
||||
emit_signal("year_changed", self.year, self.year + 1)
|
||||
self.year += 1
|
||||
self.scores.append(0)
|
||||
emit_signal("scores_updated", self.scores)
|
||||
|
||||
func advance_season():
|
||||
var t = self.current_season + 1
|
||||
var advance_year = false
|
||||
if t > SEASON.FALL:
|
||||
t = SEASON.SPRING
|
||||
advance_year = true
|
||||
# Do events for the end of the current season
|
||||
var banner = FadingText.instance()
|
||||
banner.set_text(self.season_text[t])
|
||||
banner.set_scale(Vector2(3.0, 3.0))
|
||||
banner.life_cur = 4.0
|
||||
var center = get_viewport().get_visible_rect().size / 2
|
||||
# Do this to remove some of the visual line splitting
|
||||
var size = banner.get_text_size() * banner.get_scale()
|
||||
#print("Banner text size: ", size)
|
||||
#print("Banner size: ", banner.get_size())
|
||||
banner.set_size(Vector2(size.x, size.y))
|
||||
size = banner.get_text_size() * banner.get_scale()
|
||||
banner.set_position(Vector2(center.x - size.x/2.0, 30 - min(10, size.y/2.0)))
|
||||
#print("Banner position: ", banner.get_position())
|
||||
|
||||
add_child(banner)
|
||||
# Plants consume the nutrients and health of soil + Plant effects
|
||||
#for soil in get_tree().get_nodes_in_group("soil"):
|
||||
# soil.nourish_plants_and_run_plant_effects(self.current_season, t, self.grid)
|
||||
get_tree().call_group("soil", "nourish_plants_and_run_plant_effects", self.current_season, t, self.grid)
|
||||
# Add action points
|
||||
self.update_action_points(2)
|
||||
if advance_year:
|
||||
for soil in get_tree().get_nodes_in_group("soil"):
|
||||
if soil.stored != null:
|
||||
var plant_score = soil.stored.get_score()
|
||||
self.scores[self.year] += plant_score
|
||||
if plant_score > 0:
|
||||
var f = FadingText.instance()
|
||||
f.set_text("%+d points" % plant_score)
|
||||
f.set_position(Vector2(32, 32))
|
||||
f.set_modulate(Color(0.9, 0.1, 0.9))
|
||||
soil.add_child(f)
|
||||
soil.end_of_year(self.grid)
|
||||
self.advance_year()
|
||||
self.set_season(t)
|
||||
# Any events at the start of the new season
|
||||
|
||||
func set_season(season: int):
|
||||
emit_signal("season_changed", self.current_season, season)
|
||||
self.current_season = season
|
||||
|
||||
func advance_time():
|
||||
var t = self.current_time + 1
|
||||
var advance_season = false
|
||||
print("Advancing time to ", t)
|
||||
if t > TIME.DUSK:
|
||||
t = TIME.DAWN
|
||||
advance_season = true
|
||||
# Do the things that have to be done for the old time
|
||||
# Show where light is coming from
|
||||
var group = "edge_time_%d" % self.current_time
|
||||
var sun = self.sun_strength(self.current_time, self.current_season)
|
||||
for node in get_tree().get_nodes_in_group(group):
|
||||
node.display_arrow(self.time_light_from[self.current_time],
|
||||
self.hex_height, self.hex_width, self.hex_size)
|
||||
# Calculate the light that reaches all the tiles
|
||||
var first = node
|
||||
var second = null
|
||||
var light = sun
|
||||
var last_tallest = 0
|
||||
while first != null:
|
||||
first.apply_light(light)
|
||||
last_tallest = max(last_tallest, first.get_height())
|
||||
var loc = first.pf_location + self.time_light_to[self.current_time]
|
||||
if self.grid._is_valid_q_r(loc.x, loc.y):
|
||||
second = self.grid.get_item(loc.x, loc.y)
|
||||
if second != null:
|
||||
if last_tallest > second.get_height():
|
||||
light = 0
|
||||
else:
|
||||
light = sun
|
||||
last_tallest = max(last_tallest, second.get_height())
|
||||
first = second
|
||||
second = null
|
||||
|
||||
# Run growth on tiles
|
||||
# For tiles that have no plants, weed maybe
|
||||
if advance_season:
|
||||
self.advance_season()
|
||||
self.set_time(t)
|
||||
# Any events at the start of the new time
|
||||
|
||||
func set_time(period: int):
|
||||
emit_signal("day_time_changed", self.current_time, period)
|
||||
self.current_time = period
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
if self.current_action == "pass_time":
|
||||
if self.stage_timer > 0.0:
|
||||
self.stage_timer -= delta
|
||||
else:
|
||||
self.advance_time()
|
||||
if self.current_time != TIME.DAWN:
|
||||
self.stage_timer = self.stage_time
|
||||
else:
|
||||
self.current_action = self.last_action
|
||||
self.update_current_hex_action_possibility()
|
||||
# Some other things...
|
||||
get_node("Ui/Right/VBoxContainer2/ActionMenu").unlock()
|
||||
|
||||
|
||||
func _unhandled_input(event):
|
||||
if Input.is_action_pressed("ui_cancel"):
|
||||
get_node("Ui/Menu").popup_centered()
|
||||
if Input.is_action_pressed("ui_help"):
|
||||
var help = get_node("Ui/Help")
|
||||
if help.is_visible():
|
||||
help.set_visible(false)
|
||||
else:
|
||||
help.popup_centered()
|
||||
var action_menu = get_node("Ui/Right/VBoxContainer2/ActionMenu")
|
||||
if Input.is_action_pressed("ui_plant"):
|
||||
action_menu.find_node("Plant").set_pressed(true)
|
||||
if Input.is_action_pressed("ui_query"):
|
||||
action_menu.find_node("Query").set_pressed(true)
|
||||
if Input.is_action_pressed("ui_cull"):
|
||||
action_menu.find_node("Cull").set_pressed(true)
|
||||
if Input.is_action_pressed("ui_burn"):
|
||||
action_menu.find_node("Burn").set_pressed(true)
|
||||
if Input.is_action_pressed("ui_removerock"):
|
||||
action_menu.find_node("RemoveRock").set_pressed(true)
|
||||
if Input.is_action_pressed("ui_fertilize"):
|
||||
action_menu.find_node("Fertilize").set_pressed(true)
|
||||
|
||||
func _on_Help_pressed():
|
||||
get_node("Ui/Help").popup_centered()
|
||||
|
||||
|
||||
func _on_MenuButton_pressed():
|
||||
get_node("Ui/Menu").popup_centered()
|
||||
|
||||
func _on_HexHover(hex, inside):
|
||||
#print("Hex ", hex, " at ", hex.pf_location)
|
||||
if inside:
|
||||
self.current_hex = hex
|
||||
hex.start_tooltip_timer()
|
||||
hex.get_node("Border").set_modulate(Color(0.0, 1.0, 0.0))
|
||||
self.update_current_hex_action_possibility()
|
||||
else:
|
||||
self.current_hex = null
|
||||
hex.update_tooltip("")
|
||||
hex.hide_tooltip()
|
||||
hex.get_node("Border").set_modulate(Color(1.0, 1.0, 1.0))
|
||||
self.update_current_hex_action_possibility()
|
||||
|
||||
|
||||
func update_current_hex_action_possibility():
|
||||
if self.current_hex == null:
|
||||
# Reset mouse pointer
|
||||
Input.set_default_cursor_shape(Input.CURSOR_ARROW)
|
||||
return
|
||||
# Need to check if current action be done on the hex
|
||||
# Show user why not
|
||||
var action_compat = self.current_hex.can_do_action(self.current_action)
|
||||
var applicable = action_compat[0]
|
||||
var possible = action_compat[1]
|
||||
var reason = action_compat[2]
|
||||
var cost = action_compat[3]
|
||||
if cost > self.action_points:
|
||||
possible = false
|
||||
reason = "Too few action points. Have %d, need %d" % [self.action_points, cost]
|
||||
if applicable:
|
||||
if not possible:
|
||||
Input.set_default_cursor_shape(Input.CURSOR_FORBIDDEN)
|
||||
self.current_hex.get_node("Border").set_modulate(Color(1.0, 0.0, 0.0))
|
||||
self.current_hex.update_tooltip(reason)
|
||||
else:
|
||||
Input.set_default_cursor_shape(Input.CURSOR_CAN_DROP)
|
||||
else:
|
||||
self.current_hex.get_node("Border").set_modulate(Color(0.25, 0.25, 0.25))
|
||||
|
||||
func _on_HexInputEvent(viewport, event, shape, hex):
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == BUTTON_LEFT:
|
||||
if event.pressed:
|
||||
self.hex_click_start = hex
|
||||
else:
|
||||
if self.hex_click_start == hex:
|
||||
self.do_action(hex, self.current_action)
|
||||
else:
|
||||
self.hex_click_start = null
|
||||
|
||||
func do_action(hex, action):
|
||||
# Recheck if action is possible on hex
|
||||
var action_compat = hex.can_do_action(action)
|
||||
var cost = action_compat[3]
|
||||
if not action_compat[0] or not action_compat[1]:
|
||||
return
|
||||
if cost > self.action_points:
|
||||
return
|
||||
print(action, " on ", hex)
|
||||
if action == "query":
|
||||
get_node("Ui/Right/VBoxContainer2/Details/Panel").set_text(hex.query_details())
|
||||
get_node("AudioQuery").play()
|
||||
elif action == "plant":
|
||||
print(self.current_plant)
|
||||
hex.do_action(action,
|
||||
{"plant": self.plant_types[self.current_plant].duplicate()})
|
||||
get_node("AudioPlant").play()
|
||||
elif action == "cull":
|
||||
var r = hex.do_action(action, null)
|
||||
if r != null and r > 0:
|
||||
self.scores[self.current_year] += r
|
||||
print("Got %+d from culling plant", r)
|
||||
emit_signal("scores_updated", self.scores)
|
||||
get_node("AudioCull").play()
|
||||
elif action == "burn":
|
||||
hex.do_action(action, null)
|
||||
get_node("AudioBurn").play()
|
||||
elif action == "removerock":
|
||||
hex.do_action(action, null)
|
||||
get_node("AudioRemoveRock").play()
|
||||
elif action == "fertilize":
|
||||
hex.do_action(action, null)
|
||||
get_node("AudioFertilize").play()
|
||||
else:
|
||||
print("UNKNOWN ACTION ", action)
|
||||
if (cost > 0):
|
||||
var f = FadingText.instance()
|
||||
f.set_text("%+d AP" % -cost)
|
||||
f.set_position(Vector2(32, 0))
|
||||
f.move_towards = Vector2(64, -32)
|
||||
f.set_modulate(Color(0.9, 0.1, 0.1))
|
||||
hex.add_child(f)
|
||||
self.update_action_points(-cost)
|
||||
|
||||
|
||||
func _on_action_changed(action):
|
||||
self.last_action = self.current_action
|
||||
self.current_action = action
|
||||
self.update_current_hex_action_possibility()
|
||||
if action == "pass_time":
|
||||
self.advance_time()
|
||||
self.stage_timer = self.stage_time
|
||||
|
||||
func _on_day_time_changed(old, new):
|
||||
get_node("Ui/Left/VBoxContainer/TimeLabel").set_text("Time: %s" % self.time_text[new])
|
||||
# Show a banner of the stage
|
||||
var banner = FadingText.instance()
|
||||
banner.set_text(self.time_text[old])
|
||||
banner.set_scale(Vector2(2.0, 2.0))
|
||||
var center = get_viewport().get_visible_rect().size / 2
|
||||
var size = banner.get_text_size()
|
||||
banner.set_position(Vector2(center.x - size.x/2.0, center.y*2.0 - 20 - size.y/2.0))
|
||||
add_child(banner)
|
||||
if new == TIME.DAWN:
|
||||
get_node("AudioDawn").play()
|
||||
|
||||
func _on_season_changed(old, new):
|
||||
get_node("Ui/Left/VBoxContainer/SeasonLabel").set_text("Season: %s" % self.season_text[new])
|
||||
|
||||
func _on_year_changed(old, new):
|
||||
get_node("Ui/Left/VBoxContainer/YearLabel").set_text("Year: %d" % self.year)
|
||||
|
||||
func _on_action_points_changed(old, new):
|
||||
self.update_current_hex_action_possibility()
|
||||
|
||||
func _on_plant_type_changed(value):
|
||||
self.current_plant = value
|
|
@ -0,0 +1,171 @@
|
|||
[gd_scene load_steps=15 format=2]
|
||||
|
||||
[ext_resource path="res://src/Game.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/Menu.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://src/Help.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://src/Sun.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://src/ui/PlantMenu.tscn" type="PackedScene" id=5]
|
||||
[ext_resource path="res://src/ui/ActionMenu.tscn" type="PackedScene" id=6]
|
||||
[ext_resource path="res://assets/bg.png" type="Texture" id=7]
|
||||
[ext_resource path="res://assets/Tweet.wav" type="AudioStream" id=8]
|
||||
[ext_resource path="res://assets/Plant.wav" type="AudioStream" id=9]
|
||||
[ext_resource path="res://assets/Rock.wav" type="AudioStream" id=10]
|
||||
[ext_resource path="res://assets/Query.wav" type="AudioStream" id=11]
|
||||
[ext_resource path="res://assets/Cull.wav" type="AudioStream" id=12]
|
||||
[ext_resource path="res://assets/Fertilize.wav" type="AudioStream" id=13]
|
||||
[ext_resource path="res://assets/Burn.wav" type="AudioStream" id=14]
|
||||
|
||||
[node name="Game" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Ui" type="Control" parent="."]
|
||||
margin_right = 40.0
|
||||
margin_bottom = 40.0
|
||||
|
||||
[node name="Menu" parent="Ui" instance=ExtResource( 2 )]
|
||||
|
||||
[node name="Help" parent="Ui" instance=ExtResource( 3 )]
|
||||
|
||||
[node name="Left" type="Panel" parent="Ui"]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 600.0
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Ui/Left"]
|
||||
margin_right = 40.0
|
||||
margin_bottom = 40.0
|
||||
|
||||
[node name="TimeLabel" type="Button" parent="Ui/Left/VBoxContainer"]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "When you \"Let Time Pass\", the day goes through Dawn, Morning, Afternoon, and Dusk.
|
||||
Each part of the day shines light from a different direction on to your field. The sun is strongest in the Afternoon.
|
||||
Tall items block the passage of sunlight to those behind."
|
||||
focus_mode = 0
|
||||
shortcut_in_tooltip = false
|
||||
enabled_focus_mode = 0
|
||||
text = "Time: Dawn"
|
||||
flat = true
|
||||
|
||||
[node name="SeasonLabel" type="Button" parent="Ui/Left/VBoxContainer"]
|
||||
margin_top = 24.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 44.0
|
||||
hint_tooltip = "Each Dawn is the start of a new season.
|
||||
Each new season gives you more Action Points (AP).
|
||||
At the end of the Autumn season, all the plants are automatically harvested.
|
||||
Unless a perennial survives winter, it will also be removed."
|
||||
shortcut_in_tooltip = false
|
||||
text = "Season: Spring"
|
||||
flat = true
|
||||
|
||||
[node name="YearLabel" type="Button" parent="Ui/Left/VBoxContainer"]
|
||||
margin_top = 48.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 68.0
|
||||
hint_tooltip = "The in-game year"
|
||||
shortcut_in_tooltip = false
|
||||
text = "Year: 0"
|
||||
flat = true
|
||||
|
||||
[node name="PlantMenu" parent="Ui/Left/VBoxContainer" instance=ExtResource( 5 )]
|
||||
margin_top = 72.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 395.0
|
||||
|
||||
[node name="Right" type="Panel" parent="Ui"]
|
||||
margin_left = 864.0
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 600.0
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
}
|
||||
|
||||
[node name="VBoxContainer2" type="VBoxContainer" parent="Ui/Right"]
|
||||
margin_right = 40.0
|
||||
margin_bottom = 40.0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="Ui/Right/VBoxContainer2"]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 160, 0 )
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
alignment = 1
|
||||
|
||||
[node name="Help" type="Button" parent="Ui/Right/VBoxContainer2/HBoxContainer"]
|
||||
margin_left = 33.0
|
||||
margin_right = 75.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "Help"
|
||||
text = "Help"
|
||||
icon_align = 1
|
||||
expand_icon = true
|
||||
|
||||
[node name="MenuButton" type="Button" parent="Ui/Right/VBoxContainer2/HBoxContainer"]
|
||||
margin_left = 79.0
|
||||
margin_right = 127.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "Menu"
|
||||
text = "Menu"
|
||||
align = 0
|
||||
icon_align = 1
|
||||
expand_icon = true
|
||||
|
||||
[node name="ActionMenu" parent="Ui/Right/VBoxContainer2" instance=ExtResource( 6 )]
|
||||
margin_bottom = 285.0
|
||||
|
||||
[node name="Details" type="VBoxContainer" parent="Ui/Right/VBoxContainer2"]
|
||||
margin_top = 289.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 322.0
|
||||
|
||||
[node name="Label" type="Label" parent="Ui/Right/VBoxContainer2/Details"]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 14.0
|
||||
text = "Details"
|
||||
align = 1
|
||||
valign = 1
|
||||
autowrap = true
|
||||
uppercase = true
|
||||
|
||||
[node name="Panel" type="RichTextLabel" parent="Ui/Right/VBoxContainer2/Details"]
|
||||
margin_top = 18.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 33.0
|
||||
bbcode_enabled = true
|
||||
fit_content_height = true
|
||||
|
||||
[node name="Sun" parent="." instance=ExtResource( 4 )]
|
||||
position = Vector2( 226, 335 )
|
||||
|
||||
[node name="Background" type="Sprite" parent="."]
|
||||
z_index = -2
|
||||
z_as_relative = false
|
||||
texture = ExtResource( 7 )
|
||||
centered = false
|
||||
|
||||
[node name="AudioDawn" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource( 8 )
|
||||
|
||||
[node name="AudioPlant" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource( 9 )
|
||||
|
||||
[node name="AudioQuery" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource( 11 )
|
||||
|
||||
[node name="AudioCull" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource( 12 )
|
||||
|
||||
[node name="AudioRemoveRock" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource( 10 )
|
||||
|
||||
[node name="AudioBurn" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource( 14 )
|
||||
|
||||
[node name="AudioFertilize" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource( 13 )
|
||||
|
||||
[connection signal="pressed" from="Ui/Right/VBoxContainer2/HBoxContainer/Help" to="." method="_on_Help_pressed"]
|
||||
[connection signal="pressed" from="Ui/Right/VBoxContainer2/HBoxContainer/MenuButton" to="." method="_on_MenuButton_pressed"]
|
|
@ -0,0 +1,16 @@
|
|||
extends PopupPanel
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,87 @@
|
|||
[gd_scene load_steps=6 format=2]
|
||||
|
||||
[ext_resource path="res://src/Help.gd" type="Script" id=1]
|
||||
[ext_resource path="res://assets/Bitstream Vera Sans Mono Bold Nerd Font Complete.ttf" type="DynamicFontData" id=2]
|
||||
[ext_resource path="res://assets/screenshots/tile.png" type="Texture" id=3]
|
||||
[ext_resource path="res://assets/screenshots/light.png" type="Texture" id=4]
|
||||
|
||||
[sub_resource type="DynamicFont" id=1]
|
||||
size = 40
|
||||
outline_size = 1
|
||||
font_data = ExtResource( 2 )
|
||||
|
||||
[node name="Help" type="PopupPanel"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 72.0
|
||||
margin_right = 72.0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="HBoxContainer" type="VBoxContainer" parent="."]
|
||||
margin_right = 40.0
|
||||
margin_bottom = 40.0
|
||||
|
||||
[node name="Label" type="Label" parent="HBoxContainer"]
|
||||
margin_right = 965.0
|
||||
margin_bottom = 48.0
|
||||
size_flags_horizontal = 3
|
||||
custom_colors/font_color = Color( 0.996078, 1, 0.258824, 1 )
|
||||
custom_colors/font_outline_modulate = Color( 1, 0, 0.972549, 1 )
|
||||
custom_fonts/font = SubResource( 1 )
|
||||
text = "Da 'Lil Patch"
|
||||
align = 1
|
||||
|
||||
[node name="VBoxContainer" type="HBoxContainer" parent="HBoxContainer"]
|
||||
margin_top = 52.0
|
||||
margin_right = 965.0
|
||||
margin_bottom = 508.0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer/VBoxContainer"]
|
||||
margin_right = 965.0
|
||||
margin_bottom = 456.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer/VBoxContainer/HBoxContainer"]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 456.0
|
||||
rect_min_size = Vector2( 160, 0 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="HBoxContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||
position = Vector2( 84, 63 )
|
||||
texture = ExtResource( 3 )
|
||||
|
||||
[node name="Sprite2" type="Sprite" parent="HBoxContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||
position = Vector2( 78, 223 )
|
||||
scale = Vector2( 0.623711, 0.617424 )
|
||||
texture = ExtResource( 4 )
|
||||
|
||||
[node name="Label2" type="Label" parent="HBoxContainer/VBoxContainer/HBoxContainer"]
|
||||
margin_left = 164.0
|
||||
margin_right = 965.0
|
||||
margin_bottom = 456.0
|
||||
text = "In \"Da 'Lil Patch\", the goal is to make the best use of the small plot of land you have.
|
||||
|
||||
Choose plants from the left-hand side menu, and select which actions you want to do from the right-hand side menu.
|
||||
|
||||
1. The first thing you will want to do is place some seeds down.
|
||||
2. Click pass time to see how the plants get sunlight and grow
|
||||
|
||||
At the end of each \"Autumn\" plants are harvested and give you score based on how ripe they are. Some plants, like Weeds
|
||||
and Clover, don't give any points. Some plants can take a long time to bear fruit.
|
||||
|
||||
Each plant changes the soil it's own, and potentially affects the tiles around it it.
|
||||
|
||||
The sunlight comes from four (4) different directions each time you click on \"Pass Time\": left, top-left, top-right, and right.
|
||||
The strength of the sunlight varies with the time of day and the current season. As each growth tick happens, you'll see \"+X\"
|
||||
over the plants in green for how much growth they received.
|
||||
|
||||
Some tiles also turn dark, to show that they haven't received any sunlight. When there is a plant in the tile that's taller than
|
||||
the adjacent tiles in the sunlight's path, it will shade the next tiles until a taller plant is encountered.
|
||||
|
||||
As each season passes, the plants consume nutrients and health from the soil. Most soil also accumulates rocks as the
|
||||
harvests happen. Eventually there might be big boulders on some of the tiles! Each season also gives you some more Action
|
||||
Points, which can be used to Cull (remove) plants early, Burn plants off the land, Remove Rocks, or Fertilize a tile. Each action
|
||||
has a different cost and effect explained by the tooltips.
|
||||
|
||||
You can check the scores for the years that have passed in the menu by clicking on the Menu button or hitting Escape.
|
||||
|
||||
You can press escape to close this pane, and Shift+Slash to show it again."
|
|
@ -0,0 +1,106 @@
|
|||
extends Node2D
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
var pf_location = Vector2(-1, -1)
|
||||
var stored = null
|
||||
var tooltip_timer = -1.0
|
||||
var last_light_received = 0
|
||||
var last_light_timer = 0.0
|
||||
var last_light_timer_max = 2.0
|
||||
var arrow_sprite_life_max = 2.0
|
||||
var arrow_sprite_life = 0.0
|
||||
var arrow_sprite = preload("res://assets/small arrow.png")
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func _process(delta):
|
||||
if tooltip_timer != -1.0:
|
||||
if tooltip_timer >= 0.0:
|
||||
tooltip_timer -= delta
|
||||
if tooltip_timer <= 0.0 and not get_node("Tooltip").is_visible():
|
||||
get_node("Tooltip").set_visible(true)
|
||||
if self.arrow_sprite_life > 0.0:
|
||||
self.arrow_sprite_life -= delta
|
||||
if self.arrow_sprite_life <= 0.0:
|
||||
get_node("Arrow").queue_free()
|
||||
if self.last_light_timer >= 0.0:
|
||||
self.last_light_timer -= delta
|
||||
if self.last_light_timer <= 0.0:
|
||||
get_node("Light").set_visible(false)
|
||||
if get_node("Sprite") != null:
|
||||
get_node("Sprite").set_modulate(self.get_default_modulate())
|
||||
|
||||
func start_tooltip_timer():
|
||||
self.tooltip_timer = 0.5
|
||||
|
||||
func hide_tooltip():
|
||||
get_node("Tooltip").set_visible(false)
|
||||
self.tooltip_timer = -1.0
|
||||
|
||||
func set_location(x: Vector2):
|
||||
self.pf_location = x
|
||||
self.update_tooltip("")
|
||||
|
||||
func update_tooltip(tooltip):
|
||||
if tooltip:
|
||||
tooltip += "\n"
|
||||
tooltip += "Location: " + str(pf_location.x) + "," + str(pf_location.y)
|
||||
get_node("Tooltip").set_text(tooltip)
|
||||
|
||||
func query_details():
|
||||
return "Location: " + str(pf_location.x) + "," + str(pf_location.y)
|
||||
|
||||
func can_do_action(action):
|
||||
if action == "query":
|
||||
return [true, true, "", 0]
|
||||
else:
|
||||
return [false, false, "Action not applicable: " + action, 0]
|
||||
|
||||
func do_action(action, args):
|
||||
pass
|
||||
|
||||
func get_height():
|
||||
if self.stored == null:
|
||||
return 0;
|
||||
return self.stored.height
|
||||
|
||||
func display_arrow(direction: Vector2, height, width, size):
|
||||
var s = Sprite.new()
|
||||
s.set_texture(self.arrow_sprite)
|
||||
s.set_name("Arrow")
|
||||
self.arrow_sprite_life = self.arrow_sprite_life_max
|
||||
var pos = Vector2(
|
||||
(direction.x * height * 0.75) + (direction.y * width * 0.6),
|
||||
(direction.y * size * 1.25)
|
||||
)
|
||||
s.set_position(pos)
|
||||
var angle = PI * float(-direction.x) * 0.5
|
||||
angle += PI * float(direction.y) * 0.33
|
||||
if direction.y != 0 and direction.x == 0:
|
||||
angle += PI
|
||||
s.rotate(angle)
|
||||
add_child(s)
|
||||
|
||||
func apply_light(value):
|
||||
# print("[%s] Received light: %s" % [self, value])
|
||||
self.last_light_received = value
|
||||
get_node("Light").set_text(str(self.last_light_received))
|
||||
get_node("Light").set_visible(true)
|
||||
self.last_light_timer = self.last_light_timer_max
|
||||
if get_node("Sprite") != null and value <= 0:
|
||||
get_node("Sprite").set_modulate(Color(0, 0, 0, 0.50))
|
||||
|
||||
func get_neighbours(grid, include_storage = false):
|
||||
var r = []
|
||||
var neighbours = grid.get_neighbours(self.pf_location.x, self.pf_location.y)
|
||||
if include_storage:
|
||||
return neighbours
|
||||
|
||||
func get_default_modulate():
|
||||
return Color(1.0, 1.0, 1.0, 1.0)
|
|
@ -0,0 +1,42 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://assets/hex.png" type="Texture" id=1]
|
||||
[ext_resource path="res://src/Hex.gd" type="Script" id=2]
|
||||
|
||||
[node name="Hex" type="Area2D"]
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
|
||||
polygon = PoolVector2Array( 34, -21, 0, -41, -37, -19, -37, 22, -1, 42, 34, 22 )
|
||||
|
||||
[node name="Border" type="Sprite" parent="."]
|
||||
scale = Vector2( 1.5, 1.5 )
|
||||
texture = ExtResource( 1 )
|
||||
|
||||
[node name="Tooltip" type="RichTextLabel" parent="."]
|
||||
visible = false
|
||||
margin_left = -39.0
|
||||
margin_top = 5.0
|
||||
margin_right = 101.0
|
||||
margin_bottom = 51.0
|
||||
text = "Lorem Ipsum"
|
||||
fit_content_height = true
|
||||
|
||||
[node name="Light" type="RichTextLabel" parent="."]
|
||||
visible = false
|
||||
margin_left = -38.0
|
||||
margin_top = -21.0
|
||||
margin_right = 2.0
|
||||
margin_bottom = 19.0
|
||||
text = "0"
|
||||
fit_content_height = true
|
||||
|
||||
[node name="Growth" type="RichTextLabel" parent="."]
|
||||
visible = false
|
||||
margin_left = 29.0
|
||||
margin_top = -20.0
|
||||
margin_right = 69.0
|
||||
margin_bottom = 20.0
|
||||
mouse_filter = 2
|
||||
text = "0"
|
||||
fit_content_height = true
|
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://HexGrid.gd" type="Script" id=1]
|
||||
|
||||
[node name="HexGrid" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
|
@ -0,0 +1,83 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://Menu.gd" type="Script" id=1]
|
||||
[ext_resource path="res://assets/Bitstream Vera Sans Mono Bold Nerd Font Complete.ttf" type="DynamicFontData" id=2]
|
||||
|
||||
[sub_resource type="DynamicFont" id=1]
|
||||
size = 40
|
||||
outline_size = 1
|
||||
font_data = ExtResource( 2 )
|
||||
|
||||
[node name="Menu" type="PopupPanel"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_right = -484.0
|
||||
margin_bottom = -354.0
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
margin_left = 4.0
|
||||
margin_top = 4.0
|
||||
margin_right = 536.0
|
||||
margin_bottom = 242.0
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxContainer"]
|
||||
margin_right = 532.0
|
||||
margin_bottom = 48.0
|
||||
size_flags_horizontal = 3
|
||||
custom_colors/font_color = Color( 0.996078, 1, 0.258824, 1 )
|
||||
custom_colors/font_outline_modulate = Color( 1, 0, 0.972549, 1 )
|
||||
custom_fonts/font = SubResource( 1 )
|
||||
text = "Da 'Lil Patch"
|
||||
align = 1
|
||||
|
||||
[node name="Score" type="RichTextLabel" parent="VBoxContainer"]
|
||||
margin_top = 52.0
|
||||
margin_right = 532.0
|
||||
margin_bottom = 67.0
|
||||
bbcode_enabled = true
|
||||
bbcode_text = "[center]Score: 0[/center]"
|
||||
text = "Score: 0"
|
||||
fit_content_height = true
|
||||
|
||||
[node name="ScoreByYear" type="RichTextLabel" parent="VBoxContainer"]
|
||||
margin_top = 71.0
|
||||
margin_right = 532.0
|
||||
margin_bottom = 86.0
|
||||
bbcode_enabled = true
|
||||
fit_content_height = true
|
||||
|
||||
[node name="Continue" type="Button" parent="VBoxContainer"]
|
||||
margin_top = 90.0
|
||||
margin_right = 532.0
|
||||
margin_bottom = 124.0
|
||||
size_flags_vertical = 3
|
||||
text = "Continue"
|
||||
|
||||
[node name="Restart" type="Button" parent="VBoxContainer"]
|
||||
margin_top = 128.0
|
||||
margin_right = 532.0
|
||||
margin_bottom = 162.0
|
||||
size_flags_vertical = 3
|
||||
text = "Restart"
|
||||
|
||||
[node name="Help" type="Button" parent="VBoxContainer"]
|
||||
margin_top = 166.0
|
||||
margin_right = 532.0
|
||||
margin_bottom = 200.0
|
||||
size_flags_vertical = 3
|
||||
text = "Help"
|
||||
|
||||
[node name="Quit" type="Button" parent="VBoxContainer"]
|
||||
margin_top = 204.0
|
||||
margin_right = 532.0
|
||||
margin_bottom = 238.0
|
||||
size_flags_vertical = 3
|
||||
text = "Quit"
|
||||
|
||||
[connection signal="pressed" from="VBoxContainer/Continue" to="." method="_on_Continue_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Restart" to="." method="_on_Restart_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Help" to="." method="_on_Help_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Quit" to="." method="_on_Quit_pressed"]
|
|
@ -0,0 +1,150 @@
|
|||
extends Node2D
|
||||
|
||||
|
||||
const FadingText = preload("res://src/ui/FadingText.tscn")
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
enum STAGE {SEED, SPROUT, GROWTH, FRUIT, RIPE}
|
||||
const default_sprites = [
|
||||
preload("res://assets/seeds.png"),
|
||||
preload("res://assets/sprouts.png"),
|
||||
preload("res://assets/plant.png"),
|
||||
preload("res://assets/plant.png"),
|
||||
preload("res://assets/plant.png"),
|
||||
preload("res://assets/plant.png")
|
||||
]
|
||||
var sprites = []
|
||||
var icon = preload("res://assets/hex.png")
|
||||
var icon_tooltip = "Plaaaant me"
|
||||
var description = "A plant"
|
||||
# run time
|
||||
var growth = 0
|
||||
var height = 0
|
||||
|
||||
# per-type stats
|
||||
# each stat contributes to growth during each section of the day
|
||||
# there are 4 sections to the day, and 4 growing periods
|
||||
var light_range = [15, 85] # below x too shady, above y too sunny
|
||||
var growth_mod_by_light = [2, 10, -1] # shady, ok, sunny
|
||||
|
||||
var rockiness_range = [5, 50]
|
||||
var growth_mod_by_rockiness = [-1, 10, -5]
|
||||
|
||||
var nutrient_range = [10, 100]
|
||||
var growth_mod_by_nutrition = [0, 10, 15]
|
||||
|
||||
var soil_health_range = [25, 75]
|
||||
var growth_mod_by_soil_health = [0, 5, 10]
|
||||
|
||||
var base_score = 100
|
||||
var score_mod_by_growth = [0.0, 0.0, 0.0, 0.1, 1.2, 1.5]
|
||||
var growth_thresholds = [100, 175, 250, 300, 400] # for each stage above
|
||||
var heights = [0, 0, 1, 1, 1, 1]
|
||||
|
||||
var plantable = true
|
||||
var survives_winter = false
|
||||
var season_rockiness_mod = 0
|
||||
var season_nutrient_mod = -10
|
||||
var season_health_mod = -5
|
||||
var harvest_nutrient_mod = 5
|
||||
var harvest_health_mod = 5
|
||||
var harvest_rockiness_mod = 5
|
||||
|
||||
# @TODO adjacency effects
|
||||
|
||||
static func find_by_range_area(value, ranges, mods):
|
||||
var v = 0
|
||||
for x in ranges:
|
||||
if value > x:
|
||||
v += 1
|
||||
continue
|
||||
break
|
||||
if v >= mods.size():
|
||||
v = mods.size()-1
|
||||
return mods[v]
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
get_node("Sprite").set_texture(self.sprites[self.get_stage()])
|
||||
|
||||
func get_description():
|
||||
var s = "%s\n\n" % self.description
|
||||
s += "Base score: %d\nScore mods by growth stage: %s\n\n" % [self.base_score, self.score_mod_by_growth]
|
||||
s += "At the end of each season\n\tRockiness: %d\n\tSoil health: %d\n\tSoil nutrients: %d\n\n" %[self.season_rockiness_mod, self.season_health_mod, self.season_nutrient_mod]
|
||||
s += "When harvested:\n\tRockiness: %d\n\tSoil health: %d\n\tSoil nutrients: %d\n" %[self.harvest_rockiness_mod, self.harvest_health_mod, self.harvest_nutrient_mod]
|
||||
return s
|
||||
|
||||
func _init():
|
||||
self.sprites.resize(self.default_sprites.size())
|
||||
for x in range(self.default_sprites.size()):
|
||||
if self.sprites[x] == null:
|
||||
self.sprites[x] = self.default_sprites[x]
|
||||
|
||||
func query_details():
|
||||
var stage = self.get_stage()
|
||||
var next = "N/A"
|
||||
if stage < self.growth_thresholds.size():
|
||||
next = str(self.growth_thresholds[stage])
|
||||
var s = "Growth: %d\nHeight: %d\nNext stage at: %s\n\n" % [self.growth, self.height, next]
|
||||
return s
|
||||
|
||||
func get_stage():
|
||||
var stage = 0
|
||||
for x in self.growth_thresholds:
|
||||
if self.growth >= x:
|
||||
stage += 1
|
||||
else:
|
||||
break
|
||||
return stage
|
||||
|
||||
func get_icon_tooltip():
|
||||
return self.icon_tooltip
|
||||
|
||||
func apply_light(light, soil):
|
||||
var growth_light = self.find_by_range_area(light, self.light_range, self.growth_mod_by_light)
|
||||
var growth_rockiness = self.find_by_range_area(soil.rockiness, self.rockiness_range, self.growth_mod_by_rockiness)
|
||||
var growth_health = self.find_by_range_area(soil.misc_health, self.soil_health_range, self.growth_mod_by_soil_health)
|
||||
var growth_nutrients = self.find_by_range_area(soil.nutrients, self.nutrient_range, self.growth_mod_by_nutrition)
|
||||
var growth = growth_light + growth_rockiness + growth_health + growth_nutrients
|
||||
#print("Grew %d = %d + %d + %d + %d" %[growth, growth_light, growth_rockiness, growth_health, growth_nutrients])
|
||||
self.grow(growth)
|
||||
|
||||
func grow(value):
|
||||
var index = self.get_stage()
|
||||
if index >= self.heights.size():
|
||||
index = self.heights.size() - 1
|
||||
self.growth += value
|
||||
self.height = self.heights[index]
|
||||
get_node("Height").set_text(str(self.height))
|
||||
get_node("Sprite").set_texture(self.sprites[index])
|
||||
var t = FadingText.instance()
|
||||
t.set_position(Vector2(32, -24))
|
||||
t.move_towards = Vector2(50, -60)
|
||||
t.set_text("%+d🌱🌱" % value)
|
||||
t.set_modulate(Color(0.1, 0.85, 0.1))
|
||||
t.set_scale(Vector2(1.5, 1.5))
|
||||
add_child(t)
|
||||
|
||||
func get_score():
|
||||
var mod = self.find_by_range_area(self.growth, self.growth_thresholds, self.score_mod_by_growth)
|
||||
var score = int(round(float(self.base_score) * mod))
|
||||
return score
|
||||
|
||||
func use_nutrients_and_run_plant_effects(soil, old_season, new_season, grid):
|
||||
print("plant use nitrients ", self)
|
||||
soil.update_stat("rockiness", self.season_rockiness_mod)
|
||||
soil.update_stat("nutrients", self.season_nutrient_mod)
|
||||
soil.update_stat("health", self.season_health_mod)
|
||||
|
||||
func end_of_year(soil, grid):
|
||||
soil.update_stat("nutrients", self.harvest_nutrient_mod)
|
||||
soil.update_stat("health", self.harvest_health_mod)
|
||||
if not self.survives_winter:
|
||||
soil.update_stat("rockiness", self.harvest_rockiness_mod)
|
||||
self.queue_free()
|
||||
soil.stored = null
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,19 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://src/Plant.gd" type="Script" id=1]
|
||||
|
||||
[node name="Plant" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="."]
|
||||
scale = Vector2( 1.5, 1.5 )
|
||||
|
||||
[node name="Height" type="RichTextLabel" parent="."]
|
||||
margin_left = -4.0
|
||||
margin_top = 26.0
|
||||
margin_right = 36.0
|
||||
margin_bottom = 66.0
|
||||
hint_tooltip = "Height"
|
||||
mouse_filter = 1
|
||||
text = "0"
|
||||
fit_content_height = true
|
|
@ -0,0 +1,160 @@
|
|||
extends "res://src/Hex.gd"
|
||||
|
||||
const Plant = preload("res://src/Plant.tscn")
|
||||
|
||||
signal soil_stat_changed(name, old, new)
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
var weed_rockiness_range = [20, 60]
|
||||
var weed_probability_from_rockiness = [0.05, 0.1, 0.15]
|
||||
var weed_health_range = [25, 50, 75]
|
||||
var weed_probability_from_health = [0.2, 0.15, 0.1, 0.05]
|
||||
var weed_nutrient_range = [33, 66]
|
||||
var weed_probability_from_nutrient = [0.1, 0.2, 0.3]
|
||||
var strong_weed_probability = 0.5
|
||||
|
||||
var rockiness = 0
|
||||
var nutrients = 50
|
||||
var misc_health = 50 # pH, moisture, aeration
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
static func find_by_range_area(value, ranges, mods):
|
||||
var v = 0
|
||||
for x in ranges:
|
||||
if value > x:
|
||||
v += 1
|
||||
continue
|
||||
break
|
||||
if v >= mods.size():
|
||||
v = mods.size()-1
|
||||
return mods[v]
|
||||
|
||||
func can_do_action(action):
|
||||
if action == "plant":
|
||||
return [true, self.stored == null, "", 0]
|
||||
elif action == "cull":
|
||||
return [true, self.stored != null, "You can only cull on soil tiles that have plants", 1]
|
||||
elif action == "burn":
|
||||
return [true, self.stored != null, "You can only burn soil tiles that have plants", 2]
|
||||
elif action == "removerock":
|
||||
return [true, self.rockiness >= 20, "You can only remove rocks on soil that have rocks >= 20", 3]
|
||||
elif action == "fertilize":
|
||||
return [true, true, "", 4]
|
||||
return .can_do_action(action)
|
||||
|
||||
func query_details():
|
||||
var details = "Rockiness: %d\nNutrients %d\nHealth %d\n\nPlant: %s\n" % [self.rockiness, self.nutrients, self.misc_health, str(self.stored)]
|
||||
if self.stored != null and self.stored:
|
||||
details += self.stored.query_details()
|
||||
details += "Soil gains rockiness and loses nutrients and health over time based on which plants are sown.\n\n"
|
||||
details += "If there are no plants, there's a chance that weeds grow.\n\n"
|
||||
details += .query_details()
|
||||
return details
|
||||
|
||||
func do_action(action, args):
|
||||
if action == "cull":
|
||||
assert(self.stored != null)
|
||||
var plant = self.stored
|
||||
self.stored = null
|
||||
var score = plant.get_score()
|
||||
self.update_stat("rockiness", plant.harvest_rockiness_mod)
|
||||
# @TODO do plant removal effects
|
||||
plant.queue_free()
|
||||
return score
|
||||
elif action == "plant":
|
||||
self.stored = args["plant"]
|
||||
add_child(self.stored)
|
||||
self.stored.add_to_group("runtime")
|
||||
elif action == "burn":
|
||||
assert(self.stored != null)
|
||||
var plant = self.stored
|
||||
self.stored = null
|
||||
self.update_stat("nutrients", 15)
|
||||
self.update_stat("health", -5)
|
||||
plant.queue_free()
|
||||
elif action == "removerock":
|
||||
self.update_stat("rockiness", -self.rockiness)
|
||||
elif action == "fertilize":
|
||||
self.update_stat("nutrients", 50)
|
||||
self.update_stat("health", 50)
|
||||
|
||||
func apply_light(value):
|
||||
.apply_light(value)
|
||||
if self.stored != null:
|
||||
self.stored.apply_light(value, self)
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
|
||||
func nourish_plants_and_run_plant_effects(old_season, new_season, grid):
|
||||
print("soil nourish")
|
||||
if self.stored:
|
||||
self.stored.use_nutrients_and_run_plant_effects(self, old_season, new_season, grid)
|
||||
else:
|
||||
# Increase the health of the soil slightly from not being used
|
||||
self.update_stat("misc_health", 2)
|
||||
# Chance of generating a weed
|
||||
var p_weed = 0.0
|
||||
p_weed += find_by_range_area(self.rockiness, self.weed_rockiness_range, self.weed_probability_from_rockiness)
|
||||
p_weed += find_by_range_area(self.nutrients, self.weed_nutrient_range, self.weed_probability_from_nutrient)
|
||||
p_weed += find_by_range_area(self.misc_health, self.weed_health_range, self.weed_probability_from_health)
|
||||
if randf() <= p_weed:
|
||||
var weed_name = "weed"
|
||||
if randf() > self.strong_weed_probability:
|
||||
weed_name = "strong_weed"
|
||||
var game = get_tree().current_scene
|
||||
self.do_action("plant", {"plant": game.plant_types[weed_name].duplicate()})
|
||||
|
||||
|
||||
func end_of_year(grid):
|
||||
if self.stored:
|
||||
self.stored.end_of_year(self, grid)
|
||||
#
|
||||
|
||||
func update_stat(name, value):
|
||||
var old
|
||||
var new
|
||||
if name == "rockiness":
|
||||
old = self.rockiness
|
||||
new = self.rockiness + value
|
||||
new = min(100, max(0, new))
|
||||
self.rockiness = new
|
||||
var rock_sprite = null
|
||||
if self.rockiness >= 75:
|
||||
rock_sprite = load("res://assets/rocky 3.png")
|
||||
elif self.rockiness >= 50:
|
||||
rock_sprite = load("res://assets/rocky 2.png")
|
||||
elif self.rockiness >= 20:
|
||||
rock_sprite = load("res://assets/rocky 1.png")
|
||||
if rock_sprite != null:
|
||||
get_node("Rocks").set_texture(rock_sprite)
|
||||
get_node("Rocks").set_visible(rock_sprite != null)
|
||||
elif name == "health":
|
||||
old = self.misc_health
|
||||
new = self.misc_health + value
|
||||
new = min(100, max(0, new))
|
||||
self.misc_health = new
|
||||
elif name == "nutrients":
|
||||
old = self.nutrients
|
||||
new = self.nutrients + value
|
||||
new = min(100, max(0, new))
|
||||
self.nutrients = new
|
||||
else:
|
||||
print("Unknown stat: %s" % name)
|
||||
return
|
||||
if old != new:
|
||||
emit_signal("soil_stat_changed", name, old, new)
|
||||
|
||||
func get_default_modulate():
|
||||
if self.misc_health >= 75:
|
||||
return Color("#b27308")
|
||||
elif self.misc_health >= 50:
|
||||
return Color("#da8d09")
|
||||
elif self.misc_health >= 25:
|
||||
return Color("#c49911")
|
||||
return Color("#faaf2f")
|
|
@ -0,0 +1,16 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://src/Soil.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/Hex.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://assets/soil.png" type="Texture" id=3]
|
||||
|
||||
[node name="Soil" groups=["soil"] instance=ExtResource( 2 )]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Rocks" type="Sprite" parent="." index="2"]
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="." index="3"]
|
||||
modulate = Color( 0.909804, 0.588235, 0.0352941, 1 )
|
||||
scale = Vector2( 1.5, 1.5 )
|
||||
z_index = -1
|
||||
texture = ExtResource( 3 )
|
|
@ -0,0 +1,22 @@
|
|||
extends "res://src/Hex.gd"
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
#get_node("Border").set_modulate(Color(1.0, 0.0, 0.0))
|
||||
pass # Replace with function body.
|
||||
|
||||
func query_details():
|
||||
var details = "Structure spots are tiles in which various objects may be built.\n\n"
|
||||
details += "Object: %s\n\n" % self.stored
|
||||
details += .query_details()
|
||||
return details
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Hex.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/Spot.gd" type="Script" id=2]
|
||||
|
||||
[node name="Spot" groups=["spot"] instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
|
@ -0,0 +1,25 @@
|
|||
extends Node2D
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
var goal = 0.0
|
||||
var goals = [0.0, 0.35, 0.75, 1.0]
|
||||
var speed = 0.3
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func _on_day_time_changed(old, new):
|
||||
#print("Sun time: ", new)
|
||||
self.goal = goals[new]
|
||||
|
||||
func _process(delta):
|
||||
if abs(self.goal - get_node("Path2D/PathFollow2D").get_unit_offset()) > 0.1:
|
||||
var offset = get_node("Path2D/PathFollow2D").get_unit_offset()
|
||||
offset += self.speed * delta
|
||||
if offset >= self.goal:
|
||||
offset = self.goal
|
||||
get_node("Path2D/PathFollow2D").set_unit_offset(offset)
|
|
@ -0,0 +1,26 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://assets/sun.png" type="Texture" id=1]
|
||||
[ext_resource path="res://src/Sun.gd" type="Script" id=2]
|
||||
|
||||
[sub_resource type="Curve2D" id=1]
|
||||
_data = {
|
||||
"points": PoolVector2Array( -0.840896, -10.0908, 0.840896, 10.0908, -3, -11, 0, 0, 0, 0, 9, -74, 0, 0, 0, 0, 27, -132, 0, 0, 0, 0, 45, -164, 0, 0, 0, 0, 71, -199, 0, 0, 0, 0, 100, -222, 0, 0, 0, 0, 136, -236, 0, 0, 0, 0, 172, -247, 0, 0, 0, 0, 208, -257, 0, 0, 0, 0, 243, -265, 0, 0, 0, 0, 272, -266, 0, 0, 0, 0, 317, -265, 0, 0, 0, 0, 355, -259, 0, 0, 0, 0, 389, -251, 0, 0, 0, 0, 429, -238, 0, 0, 0, 0, 455, -224, 0, 0, 0, 0, 478, -206, 0, 0, 0, 0, 506, -184, 0, 0, 0, 0, 543, -146, 0, 0, 0, 0, 559, -119, 0, 0, 0, 0, 568, -97, 0, 0, 0, 0, 579, -63, 0, 0, 0, 0, 584, -17, 0, 0, 0, 0, 589, 78 )
|
||||
}
|
||||
|
||||
[node name="Sun" type="Node2D"]
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="Path2D" type="Path2D" parent="."]
|
||||
curve = SubResource( 1 )
|
||||
|
||||
[node name="PathFollow2D" type="PathFollow2D" parent="Path2D"]
|
||||
position = Vector2( -3, -11 )
|
||||
rotation = -1.3641
|
||||
rotate = false
|
||||
lookahead = 128.411
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="Path2D/PathFollow2D"]
|
||||
rotation = -0.244346
|
||||
scale = Vector2( 2, 2 )
|
||||
texture = ExtResource( 1 )
|
|
@ -0,0 +1,35 @@
|
|||
extends "res://src/Plant.gd"
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
func _init():
|
||||
self.icon = preload("res://assets/apple icon.png")
|
||||
self.icon_tooltip = "A slow growing tree that survives over winter"
|
||||
self.description = "Delicious, but you have to plan ahead"
|
||||
self.light_range = [25, 75]
|
||||
self.season_nutrient_mod = -1
|
||||
self.season_health_mod = -1
|
||||
self.harvest_nutrient_mod = 0
|
||||
self.harvest_health_mod = 0
|
||||
self.base_score = 300
|
||||
self.sprites[2] = preload("res://assets/apple plant.png")
|
||||
self.sprites[3] = preload("res://assets/apple plant.png")
|
||||
self.sprites[4] = preload("res://assets/apple tree.png")
|
||||
self.sprites[5] = preload("res://assets/apple fruit.png")
|
||||
self.heights = [0, 1, 2, 3, 4, 5]
|
||||
self.score_mod_by_growth = [0.0, 0.0, 0.0, 0.0, 2, 3]
|
||||
self.growth_thresholds = [200, 400, 600, 800, 1000]
|
||||
self.survives_winter = true
|
||||
self.harvest_rockiness_mod = 100
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Plant.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/plants/Apple.gd" type="Script" id=2]
|
||||
|
||||
[node name="Apple" instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
|
@ -0,0 +1,30 @@
|
|||
extends "res://src/Plant.gd"
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
func _init():
|
||||
self.icon = preload("res://assets/bean icon.png")
|
||||
self.icon_tooltip = "Beans help replenish nutrients of neighbouring tiles"
|
||||
self.description = "A staple that is good at replenishing soil nutrients"
|
||||
self.light_range = [15, 75]
|
||||
self.base_score = 75
|
||||
self.season_nutrient_mod = -5
|
||||
self.harvest_nutrient_mod = 50
|
||||
self.harvest_health_mod = 0
|
||||
self.sprites[3] = preload("res://assets/bean plant.png")
|
||||
self.sprites[4] = preload("res://assets/bean plant.png")
|
||||
self.sprites[5] = preload("res://assets/bean plant.png")
|
||||
self.heights = [0, 1, 2, 2, 2, 3]
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Plant.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/plants/Bean.gd" type="Script" id=2]
|
||||
|
||||
[node name="Bean" instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
|
@ -0,0 +1,31 @@
|
|||
extends "res://src/Plant.gd"
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
func _init():
|
||||
self.icon = preload("res://assets/clover icon.png")
|
||||
self.icon_tooltip = "Clover helps replenish the health of the soil on the tile"
|
||||
self.description = "Good for the soil, and bees like it too"
|
||||
self.light_range = [10, 90]
|
||||
self.season_nutrient_mod = -1
|
||||
self.season_health_mod = 5
|
||||
self.harvest_health_mod = 10
|
||||
self.harvest_rockiness_mod = 0
|
||||
self.base_score = 0
|
||||
self.sprites[2] = preload("res://assets/clover plant.png")
|
||||
self.sprites[3] = preload("res://assets/clover plant.png")
|
||||
self.sprites[4] = preload("res://assets/clover flower.png")
|
||||
self.sprites[5] = preload("res://assets/clover flower.png")
|
||||
self.heights = [0, 1, 1, 1, 1, 1]
|
||||
self.growth_thresholds = [25, 50, 75, 100, 110, 125]
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Plant.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/plants/Clover.gd" type="Script" id=2]
|
||||
|
||||
[node name="Clover" instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
|
@ -0,0 +1,23 @@
|
|||
extends "res://src/Plant.gd"
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
func _init():
|
||||
self.icon = preload("res://assets/icon corn.png")
|
||||
self.icon_tooltip = "Corn needs lots of nutrients and light, but can be very productive"
|
||||
self.description = "A staple crop that grows well in sun"
|
||||
self.light_range = [25, 98]
|
||||
self.sprites[3] = preload("res://assets/corn fruit.png")
|
||||
self.sprites[4] = preload("res://assets/corn ripe.png")
|
||||
self.sprites[5] = preload("res://assets/corn ripe.png")
|
||||
self.heights = [0, 1, 2, 3, 3, 3]
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Plant.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/plants/Corn.gd" type="Script" id=2]
|
||||
|
||||
[node name="Corn" instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
|
@ -0,0 +1,31 @@
|
|||
extends "res://src/Plant.gd"
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
# grows tall and saps the nutrients from adjoining soil
|
||||
func _init():
|
||||
self.light_range = [5, 95]
|
||||
self.base_score = 0
|
||||
self.harvest_rockiness_mod = 25
|
||||
self.season_nutrient_mod = -10
|
||||
self.growth_thresholds = [75, 100, 140, 175, 20000]
|
||||
self.heights = [0, 1, 2, 3, 3, 3]
|
||||
self.survives_winter = true
|
||||
self.plantable = false
|
||||
self.icon = preload("res://assets/strong weed icon.png")
|
||||
self.sprites[3] = preload("res://assets/strong weed plant.png")
|
||||
self.sprites[4] = preload("res://assets/strong weed plant.png")
|
||||
self.sprites[5] = preload("res://assets/strong weed plant.png")
|
||||
self.description = "Ouch, prickly!"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/Plant.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://src/plants/StrongWeed.gd" type="Script" id=2]
|
||||
|
||||
[node name="StrongWeed" instance=ExtResource( 1 )]
|
||||
script = ExtResource( 2 )
|
|
@ -0,0 +1,33 @@
|
|||
extends "res://src/Plant.gd"
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
# Grows fast, but short and it's tough roots drag rocks up when removed
|
||||
|
||||
func _init():
|
||||
self.light_range = [20, 80]
|
||||
self.base_score = 0
|
||||
self.harvest_rockiness_mod = 15
|
||||
self.season_nutrient_mod = -15
|
||||
self.growth_thresholds = [50, 75, 100, 125, 150]
|
||||
self.heights = [0, 1, 1, 1, 2, 2]
|
||||
self.plantable = false
|
||||
self.icon = preload("res://assets/weed icon.png")
|
||||
self.sprites[3] = preload("res://assets/weed plant.png")
|
||||
self.sprites[4] = preload("res://assets/weed plant.png")
|
||||
self.sprites[5] = preload("res://assets/weed plant.png")
|
||||
self.description = "It noms nutrients and its roots pull up lots of rocks"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func use_nutrients_and_run_plant_effects(soil, old_season, new_season, grid):
|
||||
# For each soil neighbour, use it's nutrients
|
||||
.use_nutrients_and_run_plant_effects(soil, old_season, new_season, grid)
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/plants/Weed.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/Plant.tscn" type="PackedScene" id=2]
|
||||
|
||||
[node name="Weed" instance=ExtResource( 2 )]
|
||||
script = ExtResource( 1 )
|
|
@ -0,0 +1,13 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://test.gd" type="Script" id=1]
|
||||
|
||||
[node name="Area2D" type="Area2D"]
|
||||
position = Vector2( -4, -2 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
|
||||
position = Vector2( 14, 14 )
|
||||
polygon = PoolVector2Array( 9, -10, -8, -10, -9, 2, 0, 0, 0, 0, 0, 0, 0, 0 )
|
||||
|
||||
[connection signal="mouse_entered" from="." to="." method="_on_Area2D_mouse_entered"]
|
|
@ -0,0 +1,55 @@
|
|||
extends VBoxContainer
|
||||
|
||||
const FadingText = preload("res://src/ui/FadingText.tscn")
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
signal action_changed(new_value)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
for c in get_node("Grid").get_children():
|
||||
c.connect("toggled", self, "_on_ActionButton_toggled", [c.get_name().to_lower()])
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
|
||||
func _on_ActionButton_toggled(pressed, action_name):
|
||||
var another_pressed = false
|
||||
for child in get_node("Grid").get_children():
|
||||
if child.get_name().to_lower() != action_name:
|
||||
if child.is_pressed():
|
||||
another_pressed = true
|
||||
child.set_pressed(false)
|
||||
break;
|
||||
if not another_pressed and not pressed:
|
||||
for child in get_node("Grid").get_children():
|
||||
if child.get_name().to_lower() == action_name:
|
||||
child.set_pressed(true)
|
||||
return
|
||||
if pressed:
|
||||
emit_signal("action_changed", action_name)
|
||||
|
||||
func _on_PassTime_pressed():
|
||||
get_node("PassTime").set_disabled(true)
|
||||
for c in get_node("Grid").get_children():
|
||||
c.set_disabled(true)
|
||||
emit_signal("action_changed", "pass_time")
|
||||
|
||||
|
||||
func unlock():
|
||||
get_node("PassTime").set_disabled(false)
|
||||
for c in get_node("Grid").get_children():
|
||||
c.set_disabled(false)
|
||||
|
||||
func _on_action_points_changed(old, new):
|
||||
get_node("ActionPoints").set_text("Action Points: %d" % new)
|
||||
if new > old:
|
||||
var f = FadingText.instance()
|
||||
f.set_text("%+d AP" % (new - old))
|
||||
f.set_modulate(Color(0.0, 0.9, 0.1))
|
||||
add_child(f)
|
|
@ -0,0 +1,102 @@
|
|||
[gd_scene load_steps=8 format=2]
|
||||
|
||||
[ext_resource path="res://assets/icon plant.png" type="Texture" id=1]
|
||||
[ext_resource path="res://assets/icon cull.png" type="Texture" id=2]
|
||||
[ext_resource path="res://src/ui/ActionMenu.gd" type="Script" id=3]
|
||||
[ext_resource path="res://assets/icon query.png" type="Texture" id=4]
|
||||
[ext_resource path="res://assets/icon remove rock.png" type="Texture" id=5]
|
||||
[ext_resource path="res://assets/icon burn.png" type="Texture" id=6]
|
||||
[ext_resource path="res://assets/icon fertilize.png" type="Texture" id=7]
|
||||
|
||||
[node name="ActionMenu" type="VBoxContainer"]
|
||||
margin_top = 24.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 87.0
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="ActionPoints" type="RichTextLabel" parent="."]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 15.0
|
||||
text = "Action Points: 3"
|
||||
fit_content_height = true
|
||||
|
||||
[node name="Grid" type="GridContainer" parent="."]
|
||||
margin_top = 19.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 237.0
|
||||
columns = 2
|
||||
|
||||
[node name="Plant" type="Button" parent="Grid"]
|
||||
margin_right = 76.0
|
||||
margin_bottom = 70.0
|
||||
hint_tooltip = "Plant (a)
|
||||
Cost: 0 AP
|
||||
Select a plant from the plant menu on the left, and click a soil tile to plant seeds there."
|
||||
toggle_mode = true
|
||||
shortcut_in_tooltip = false
|
||||
pressed = true
|
||||
icon = ExtResource( 1 )
|
||||
icon_align = 1
|
||||
|
||||
[node name="Query" type="Button" parent="Grid"]
|
||||
margin_left = 80.0
|
||||
margin_right = 156.0
|
||||
margin_bottom = 70.0
|
||||
hint_tooltip = "Query (s)
|
||||
Click on a tile to show more detail information"
|
||||
toggle_mode = true
|
||||
icon = ExtResource( 4 )
|
||||
|
||||
[node name="Cull" type="Button" parent="Grid"]
|
||||
margin_top = 74.0
|
||||
margin_right = 76.0
|
||||
margin_bottom = 144.0
|
||||
hint_tooltip = "Cull / Harvest (d)
|
||||
Cost: 1 AP
|
||||
Select a tile to remove any of the plants on it."
|
||||
toggle_mode = true
|
||||
icon = ExtResource( 2 )
|
||||
icon_align = 1
|
||||
|
||||
[node name="Burn" type="Button" parent="Grid"]
|
||||
margin_left = 80.0
|
||||
margin_top = 74.0
|
||||
margin_right = 156.0
|
||||
margin_bottom = 144.0
|
||||
hint_tooltip = "Burn (f)
|
||||
Cost: 2 AP
|
||||
Select a tile to remove any of the plants on it with fire. Doing so does not increase rockiness, and adds nutrients but reduces soil health."
|
||||
toggle_mode = true
|
||||
icon = ExtResource( 6 )
|
||||
icon_align = 1
|
||||
|
||||
[node name="RemoveRock" type="Button" parent="Grid"]
|
||||
margin_top = 148.0
|
||||
margin_right = 76.0
|
||||
margin_bottom = 218.0
|
||||
hint_tooltip = "Remove Rock (g)
|
||||
Cost: 3 AP
|
||||
Select a tile to a reduce it's rockiness to 0"
|
||||
toggle_mode = true
|
||||
icon = ExtResource( 5 )
|
||||
icon_align = 1
|
||||
|
||||
[node name="Fertilize" type="Button" parent="Grid"]
|
||||
margin_left = 80.0
|
||||
margin_top = 148.0
|
||||
margin_right = 156.0
|
||||
margin_bottom = 218.0
|
||||
hint_tooltip = "Fertilize (h)
|
||||
Cost: 4 AP
|
||||
Greatly increase the nutirents and health of soil"
|
||||
toggle_mode = true
|
||||
icon = ExtResource( 7 )
|
||||
icon_align = 1
|
||||
|
||||
[node name="PassTime" type="Button" parent="."]
|
||||
margin_top = 241.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 261.0
|
||||
text = "Let time pass"
|
||||
|
||||
[connection signal="pressed" from="PassTime" to="." method="_on_PassTime_pressed"]
|
|
@ -0,0 +1,44 @@
|
|||
extends RichTextLabel
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
var life_max = 1.5
|
||||
var life_cur = life_max
|
||||
var autostart = true
|
||||
var started = false
|
||||
var move_towards = false
|
||||
var move_speed = 10
|
||||
|
||||
func get_text_size():
|
||||
var f = self.get_theme_default_font()
|
||||
return f.get_string_size(self.get_text())
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
if self.autostart:
|
||||
self.started = true
|
||||
print(self.get_position())
|
||||
|
||||
func _process(delta):
|
||||
if not started:
|
||||
return
|
||||
self.life_cur -= delta
|
||||
if self.life_cur <= 0.0:
|
||||
self.set_visible(false)
|
||||
self.started = false
|
||||
self.queue_free()
|
||||
else:
|
||||
var m = self.get_modulate()
|
||||
var a = self.life_cur / self.life_max
|
||||
m = Color(m.r, m.g, m.b, a)
|
||||
self.set_modulate(m)
|
||||
if self.move_towards is Vector2:
|
||||
var new_pos = self.get_position().move_toward(self.move_towards, delta * self.move_speed)
|
||||
self.set_position(new_pos)
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
|
@ -0,0 +1,18 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://src/ui/FadingText.gd" type="Script" id=1]
|
||||
[ext_resource path="res://src/ui/ThemeWithFontOutline.tres" type="Theme" id=2]
|
||||
|
||||
[node name="FadingText" type="RichTextLabel"]
|
||||
margin_bottom = 75.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
rect_min_size = Vector2( 100, 100 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
size_flags_horizontal = 3
|
||||
theme = ExtResource( 2 )
|
||||
bbcode_enabled = true
|
||||
fit_content_height = true
|
||||
scroll_active = false
|
||||
script = ExtResource( 1 )
|
|
@ -0,0 +1,9 @@
|
|||
[gd_resource type="DynamicFont" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://assets/Bitstream Vera Sans Mono Bold Nerd Font Complete.ttf" type="DynamicFontData" id=1]
|
||||
|
||||
[resource]
|
||||
size = 18
|
||||
outline_size = 1
|
||||
outline_color = Color( 0, 0, 0, 1 )
|
||||
font_data = ExtResource( 1 )
|
|
@ -0,0 +1,63 @@
|
|||
extends VBoxContainer
|
||||
|
||||
signal plant_type_changed(name)
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
func set_plants(plant_types):
|
||||
var i = 1
|
||||
for x in plant_types:
|
||||
if not plant_types[x].plantable and false:
|
||||
continue
|
||||
var button = Button.new()
|
||||
#button.set_normal_texture(plant_types[x].icon)
|
||||
button.set_button_icon(plant_types[x].icon)
|
||||
button.set_toggle_mode(true)
|
||||
if i <= 10:
|
||||
var short = ShortCut.new()
|
||||
var ip = InputEventKey.new()
|
||||
ip.set_scancode(KEY_0 + (i % 10))
|
||||
short.set_shortcut(ip)
|
||||
button.set_shortcut(short)
|
||||
button.connect("toggled", self, "_on_plant_icon_toggled", [button, x])
|
||||
get_node("Plants").add_child(button)
|
||||
button.set_tooltip(plant_types[x].get_icon_tooltip())
|
||||
# Drag and drop
|
||||
if i == 1:
|
||||
self._on_plant_icon_toggled(true, button, x)
|
||||
i += 1
|
||||
|
||||
func _on_plant_icon_toggled(pressed, button, plant_type_name):
|
||||
var another_pressed = false
|
||||
for child in get_node("Plants").get_children():
|
||||
if child != button:
|
||||
if child.is_pressed():
|
||||
another_pressed = true
|
||||
break;
|
||||
if not another_pressed and not pressed:
|
||||
button.set_pressed(true)
|
||||
return
|
||||
if pressed:
|
||||
for child in get_node("Plants").get_children():
|
||||
if child == button:
|
||||
continue
|
||||
child.set_pressed(false)
|
||||
else:
|
||||
get_node("Details").set_bbcode("")
|
||||
if (pressed):
|
||||
var game = get_tree().current_scene
|
||||
if game.plant_types[plant_type_name] != null:
|
||||
get_node("Details").set_bbcode("%s\n\n%s" %[plant_type_name.capitalize(), game.plant_types[plant_type_name].get_description()])
|
||||
emit_signal("plant_type_changed", plant_type_name)
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://src/ui/PlantMenu.gd" type="Script" id=1]
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer"]
|
||||
margin_bottom = 23.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="RichTextLabel" type="RichTextLabel" parent="."]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 15.0
|
||||
bbcode_enabled = true
|
||||
bbcode_text = "[center]Plants[/center]"
|
||||
text = "Plants"
|
||||
fit_content_height = true
|
||||
|
||||
[node name="Plants" type="GridContainer" parent="."]
|
||||
margin_top = 19.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 19.0
|
||||
columns = 2
|
||||
|
||||
[node name="Details" type="RichTextLabel" parent="."]
|
||||
margin_top = 23.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 323.0
|
||||
rect_min_size = Vector2( 160, 300 )
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
bbcode_enabled = true
|
||||
bbcode_text = "Lorem Ipsum"
|
||||
text = "Lorem Ipsum"
|
|
@ -0,0 +1,6 @@
|
|||
[gd_resource type="Theme" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://src/ui/FontOutline.tres" type="DynamicFont" id=1]
|
||||
|
||||
[resource]
|
||||
default_font = ExtResource( 1 )
|
|
@ -0,0 +1,20 @@
|
|||
extends Area2D
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
|
||||
|
||||
func _on_Area2D_mouse_entered():
|
||||
print("IN!")
|