Zmiany
This commit is contained in:
parent
6658adf389
commit
1ad22be08e
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@
|
||||
export_presets.cfg
|
||||
Randoloot.console.exe
|
||||
Randoloot.exe
|
||||
/builds/
|
||||
|
||||
24
EXPORT_WINDOWS.md
Normal file
24
EXPORT_WINDOWS.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Eksport do jednego EXE
|
||||
|
||||
1. W Godocie zainstaluj Export Templates zgodne z wersją edytora (obecnie 4.7.2).
|
||||
2. Otwórz Project → Export i wybierz preset Randoloot / Windows Desktop.
|
||||
3. Ustaw architekturę x86_64, Embed PCK włączone i Export Console Wrapper wyłączone.
|
||||
4. Użyj Export Project i wyłącz Export With Debug. Docelowa ścieżka: `builds/windows/Randoloot.exe`.
|
||||
|
||||
Do przekazania graczowi wystarczy ten EXE. Zasoby są wbudowane. Godot nie musi być zainstalowany na komputerze gracza; potrzebny jest Windows 64-bit i sterownik graficzny obsługujący Vulkan. Projekt używa Vulkan zamiast Direct3D 12, aby eksport nie potrzebował dodatkowych bibliotek Agility SDK / PIX.
|
||||
|
||||
Folder `builds` jest pomijany przez Godota i Git. Lokalny `export_presets.cfg` jest już ignorowany przez Git; przy przenoszeniu projektu należy odtworzyć powyższe ustawienia eksportu.
|
||||
|
||||
## Ścieżki i zasoby
|
||||
|
||||
- W PCK wielkość liter ma znaczenie. Ścieżka musi dokładnie odpowiadać nazwie na dysku, np. `res://assets/Ships/Spaceship_0.png`.
|
||||
- Importowane grafiki i dźwięki wczytuj przez `load()` / `preload()` / ResourceLoader. Surowy FileAccess nie gwarantuje dostępu do oryginalnego pliku po eksporcie.
|
||||
- Dane zapisywane podczas gry powinny korzystać z `user://`, ponieważ `res://` w EXE jest tylko do odczytu.
|
||||
- Po eksporcie sprawdź EXE w osobnym folderze bez plików projektu.
|
||||
|
||||
## Dokumentacja
|
||||
|
||||
- https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_windows.html
|
||||
- https://docs.godotengine.org/en/stable/classes/class_editorexportplatformwindows.html
|
||||
- https://docs.godotengine.org/en/stable/classes/class_fileaccess.html
|
||||
- https://docs.godotengine.org/en/stable/tutorials/best_practices/project_organization.html
|
||||
BIN
assets/Ships/alien_ship.jpg
Normal file
BIN
assets/Ships/alien_ship.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
@ -15,10 +15,6 @@ run/main_scene="res://scenes/ui/main_menu.tscn"
|
||||
config/features=PackedStringArray("4.7", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[audio]
|
||||
|
||||
buses/default_bus_layout="res://default_bus_layout.tres"
|
||||
|
||||
[autoload]
|
||||
|
||||
GameState="*res://scripts/game/game_state.gd"
|
||||
@ -88,7 +84,3 @@ ship_fire_secondary={
|
||||
|
||||
3d/physics_engine="Jolt Physics"
|
||||
common/physics_interpolation=true
|
||||
|
||||
[rendering]
|
||||
|
||||
rendering_device/driver.windows="d3d12"
|
||||
|
||||
@ -7,7 +7,7 @@ script = ExtResource("1_definition")
|
||||
item_id = "machine_gun"
|
||||
display_name = "Działko maszynowe"
|
||||
category = 0
|
||||
description = "Bardzo szybkostrzelna broń kinetyczna."
|
||||
description = "Bardzo szybkostrzelna broń kinetyczna. Zużywa 1 sztukę amunicji na strzał."
|
||||
primary_stat = "damage"
|
||||
primary_value = 4.0
|
||||
stat_suffix = " DMG"
|
||||
@ -15,7 +15,7 @@ weapon_kind = 1
|
||||
fire_interval = 0.1
|
||||
projectile_speed = 1150.0
|
||||
weapon_range = 550.0
|
||||
energy_cost = 3.0
|
||||
energy_cost = 0.0
|
||||
damage_lower_roll_min = 2
|
||||
damage_lower_roll_max = 4
|
||||
damage_spread_roll_min = 1
|
||||
|
||||
@ -71,10 +71,16 @@ layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_colors/font_color = Color(0.59, 0.67, 0.75, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Usługi w przygotowaniu"
|
||||
text = "Kup amunicję do działka maszynowego."
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="BuyAmmunitionButton" type="Button" parent="Center/Panel/Contents"]
|
||||
custom_minimum_size = Vector2(0, 44)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 15
|
||||
text = "KUP 100 AMUNICJI — 100 KREDYTÓW"
|
||||
|
||||
[node name="NextButton" type="Button" parent="Center/Panel/Contents"]
|
||||
custom_minimum_size = Vector2(0, 44)
|
||||
layout_mode = 2
|
||||
|
||||
@ -49,6 +49,22 @@ layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "ZAMKNIJ"
|
||||
|
||||
[node name="Ammunition" type="HBoxContainer" parent="Contents"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Count" type="Label" parent="Contents/Ammunition"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "AMUNICJA: 300"
|
||||
|
||||
[node name="CraftButton" type="Button" parent="Contents/Ammunition"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 11
|
||||
text = "TWÓRZ +100 AMUNICJI (50 części)"
|
||||
tooltip_text = "Zamień 50 części na 100 sztuk amunicji do działka maszynowego."
|
||||
|
||||
[node name="CargoGrid" type="GridContainer" parent="Contents"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
|
||||
@ -8,15 +8,11 @@ func _ready() -> void:
|
||||
push_error("SceneMusicPlayer has no track_path configured.")
|
||||
return
|
||||
|
||||
var audio_data := FileAccess.get_file_as_bytes(track_path)
|
||||
if audio_data.is_empty():
|
||||
push_error("Could not read music track: %s" % track_path)
|
||||
return
|
||||
|
||||
var music_stream := AudioStreamMP3.load_from_buffer(audio_data)
|
||||
var music_stream := load(track_path) as AudioStreamMP3
|
||||
if music_stream == null:
|
||||
push_error("Could not decode music track: %s" % track_path)
|
||||
return
|
||||
music_stream = music_stream.duplicate() as AudioStreamMP3
|
||||
music_stream.loop = true
|
||||
stream = music_stream
|
||||
volume_db = playback_volume_db
|
||||
|
||||
@ -9,15 +9,11 @@ var _ship: CharacterBody2D
|
||||
|
||||
func _ready() -> void:
|
||||
_ship = get_parent() as CharacterBody2D
|
||||
var audio_data := FileAccess.get_file_as_bytes(ENGINE_SOUND_PATH)
|
||||
if audio_data.size() <= 44:
|
||||
push_error("Could not read engine sound: %s" % ENGINE_SOUND_PATH)
|
||||
return
|
||||
|
||||
var engine_stream := AudioStreamMP3.load_from_buffer(audio_data)
|
||||
var engine_stream := load(ENGINE_SOUND_PATH) as AudioStreamMP3
|
||||
if engine_stream == null:
|
||||
push_error("Could not decode engine sound: %s" % ENGINE_SOUND_PATH)
|
||||
return
|
||||
engine_stream = engine_stream.duplicate() as AudioStreamMP3
|
||||
engine_stream.loop = true
|
||||
stream = engine_stream
|
||||
volume_db = SILENT_VOLUME_DB
|
||||
|
||||
@ -25,7 +25,7 @@ static func play(parent: Node, source_position: Vector2, weapon_kind: int, volum
|
||||
return
|
||||
if not _streams.has(weapon_kind):
|
||||
var sound_path: String = SOUND_PATHS[weapon_kind]
|
||||
_streams[weapon_kind] = AudioStreamMP3.load_from_buffer(FileAccess.get_file_as_bytes(sound_path))
|
||||
_streams[weapon_kind] = load(sound_path) as AudioStreamMP3
|
||||
var stream := _streams[weapon_kind] as AudioStreamMP3
|
||||
if stream == null:
|
||||
return
|
||||
|
||||
@ -107,7 +107,7 @@ func _physics_process(delta: float) -> void:
|
||||
_fire_projectile(item)
|
||||
_shot_timers[slot_index] = definition.weapon_cooldown
|
||||
_:
|
||||
if _shot_timers[slot_index] <= 0.0 and _consume_energy(item.get_energy_cost()):
|
||||
if _shot_timers[slot_index] <= 0.0 and _consume_shot_resource(item):
|
||||
_fire_projectile(item)
|
||||
_shot_timers[slot_index] = definition.fire_interval
|
||||
for slot_index in 2:
|
||||
@ -173,6 +173,11 @@ func _muzzle_position() -> Vector2:
|
||||
var forward := Vector2.UP.rotated(ship.rotation)
|
||||
return ship.global_position + forward * 28.0
|
||||
|
||||
func _consume_shot_resource(item: ItemInstance) -> bool:
|
||||
if item.definition.weapon_kind == ItemDefinition.WeaponKind.MACHINE_GUN:
|
||||
return inventory.consume_ammunition()
|
||||
return _consume_energy(item.get_energy_cost())
|
||||
|
||||
func _consume_energy(amount: float) -> bool:
|
||||
var current_energy := float(ship.get("energy"))
|
||||
if current_energy < amount:
|
||||
|
||||
@ -53,6 +53,8 @@ func roll_damage() -> float:
|
||||
func get_energy_cost() -> float:
|
||||
if definition == null or definition.category != ItemDefinition.Category.WEAPON:
|
||||
return 0.0
|
||||
if definition.weapon_kind == ItemDefinition.WeaponKind.MACHINE_GUN:
|
||||
return 0.0
|
||||
# Compare this weapon with its starter damage. Captain/global gear buffs are free.
|
||||
var base_lower := roundf((definition.damage_lower_roll_min + definition.damage_lower_roll_max) * 0.5)
|
||||
var base_spread := roundf((definition.damage_spread_roll_min + definition.damage_spread_roll_max) * 0.5)
|
||||
@ -109,7 +111,10 @@ func get_tooltip_text() -> String:
|
||||
lines.append("Regeneracja generatora: +%.1f /s" % (energy_regeneration_override if energy_regeneration_override >= 0.0 else definition.energy_regeneration_bonus))
|
||||
if definition.category == ItemDefinition.Category.WEAPON:
|
||||
lines.append("Każdy strzał / impuls losuje obrażenia z tego zakresu.")
|
||||
lines.append("Zasięg: %.0f px • Energia: %.1f / strzał" % [definition.weapon_range, get_energy_cost()])
|
||||
if definition.weapon_kind == ItemDefinition.WeaponKind.MACHINE_GUN:
|
||||
lines.append("Zasięg: %.0f px • Amunicja: 1 / strzał" % definition.weapon_range)
|
||||
else:
|
||||
lines.append("Zasięg: %.0f px • Energia: %.1f / strzał" % [definition.weapon_range, get_energy_cost()])
|
||||
lines.append("Odstęp strzałów: %.2f s" % maxf(definition.fire_interval, definition.weapon_cooldown))
|
||||
if not additional_modifiers.is_empty():
|
||||
lines.append("\nADDONY (aktywne po zamontowaniu)")
|
||||
|
||||
@ -2,10 +2,18 @@ extends Node
|
||||
class_name ShipInventory
|
||||
|
||||
signal inventory_changed
|
||||
signal ammunition_changed
|
||||
|
||||
const CARGO_SIZE := 20
|
||||
const WEAPON_SLOT_COUNT := 2
|
||||
const MODULE_SLOT_COUNT := 6
|
||||
const STARTING_AMMUNITION := 300
|
||||
const AMMUNITION_CRAFT_AMOUNT := 100
|
||||
const AMMUNITION_CRAFT_PARTS_COST := 50.0
|
||||
const AMMUNITION_BUY_AMOUNT := 100
|
||||
const AMMUNITION_BUY_BASE_COST := 20
|
||||
|
||||
var ammunition: int = STARTING_AMMUNITION
|
||||
|
||||
var cargo: Array[ItemInstance] = []
|
||||
var weapon_slots: Array[ItemInstance] = []
|
||||
@ -24,6 +32,7 @@ func _ready() -> void:
|
||||
cargo.assign(GameState.restart_inventory["cargo"])
|
||||
weapon_slots.assign(GameState.restart_inventory["weapon"])
|
||||
module_slots.assign(GameState.restart_inventory["module"])
|
||||
ammunition = int(GameState.restart_inventory.get("ammunition", STARTING_AMMUNITION))
|
||||
GameState.restart_inventory.clear()
|
||||
_recalculate_ship_stats()
|
||||
inventory_changed.emit()
|
||||
@ -41,14 +50,49 @@ func preserve_for_restart() -> void:
|
||||
"cargo": cargo.duplicate(),
|
||||
"weapon": weapon_slots.duplicate(),
|
||||
"module": module_slots.duplicate(),
|
||||
"ammunition": ammunition,
|
||||
}
|
||||
|
||||
func consume_ammunition() -> bool:
|
||||
if ammunition <= 0:
|
||||
return false
|
||||
ammunition -= 1
|
||||
ammunition_changed.emit()
|
||||
return true
|
||||
|
||||
func can_craft_ammunition() -> bool:
|
||||
return GameState.captain.parts >= AMMUNITION_CRAFT_PARTS_COST
|
||||
|
||||
func craft_ammunition() -> bool:
|
||||
if not can_craft_ammunition():
|
||||
return false
|
||||
GameState.captain.parts -= AMMUNITION_CRAFT_PARTS_COST
|
||||
ammunition += AMMUNITION_CRAFT_AMOUNT
|
||||
GameState.captain.emit_changed()
|
||||
ammunition_changed.emit()
|
||||
return true
|
||||
|
||||
func get_item(slot_kind: String, index: int) -> ItemInstance:
|
||||
var slots := _get_slots(slot_kind)
|
||||
if index < 0 or index >= slots.size():
|
||||
return null
|
||||
return slots[index]
|
||||
|
||||
func get_ammunition_buy_cost() -> int:
|
||||
return AMMUNITION_BUY_BASE_COST * maxi(1, GameState.system_level)
|
||||
|
||||
func can_buy_ammunition() -> bool:
|
||||
return GameState.captain.credits >= get_ammunition_buy_cost()
|
||||
|
||||
func buy_ammunition() -> bool:
|
||||
if not can_buy_ammunition():
|
||||
return false
|
||||
GameState.captain.credits -= get_ammunition_buy_cost()
|
||||
ammunition += AMMUNITION_BUY_AMOUNT
|
||||
GameState.captain.emit_changed()
|
||||
ammunition_changed.emit()
|
||||
return true
|
||||
|
||||
func add_item(item: ItemInstance) -> bool:
|
||||
if item == null or item.definition == null:
|
||||
return false
|
||||
@ -122,34 +166,11 @@ func _recalculate_ship_stats() -> void:
|
||||
ship.call("apply_equipment_bonuses", bonuses)
|
||||
|
||||
func _add_starter_items() -> void:
|
||||
var starter_items := [
|
||||
"res://resources/items/plasma_cannon.tres",
|
||||
"res://resources/items/beam_laser.tres",
|
||||
"res://resources/items/machine_gun.tres",
|
||||
"res://resources/items/missile_launcher.tres",
|
||||
"res://resources/items/reinforced_shield.tres",
|
||||
"res://resources/items/hull_plating.tres",
|
||||
"res://resources/items/compact_generator.tres",
|
||||
"res://resources/items/engine_extension.tres",
|
||||
"res://resources/items/tuned_thrusters.tres",
|
||||
"res://resources/items/shield_recharger.tres",
|
||||
"res://resources/items/afterburner.tres",
|
||||
"res://resources/items/shield_charge.tres",
|
||||
"res://resources/items/repair_drones.tres",
|
||||
]
|
||||
var cargo_index := 0
|
||||
var weapon_index := 0
|
||||
for path in starter_items:
|
||||
var definition := load(path) as ItemDefinition
|
||||
if definition == null:
|
||||
push_warning("Could not load starter item: %s" % path)
|
||||
continue
|
||||
var item := ItemInstance.new()
|
||||
item.definition = definition
|
||||
item.item_level = 1
|
||||
if definition.category == ItemDefinition.Category.WEAPON and weapon_index < WEAPON_SLOT_COUNT:
|
||||
weapon_slots[weapon_index] = item
|
||||
weapon_index += 1
|
||||
else:
|
||||
cargo[cargo_index] = item
|
||||
cargo_index += 1
|
||||
var definition := load("res://resources/items/plasma_cannon.tres") as ItemDefinition
|
||||
if definition == null:
|
||||
push_warning("Could not load starter plasma cannon")
|
||||
return
|
||||
var item := ItemInstance.new()
|
||||
item.definition = definition
|
||||
item.item_level = 1
|
||||
weapon_slots[0] = item
|
||||
|
||||
@ -5,16 +5,37 @@ signal closed
|
||||
|
||||
@onready var next_button: Button = $Center/Panel/Contents/NextButton
|
||||
@onready var close_button: Button = $Center/Panel/Contents/CloseButton
|
||||
@onready var buy_ammunition_button: Button = $Center/Panel/Contents/BuyAmmunitionButton
|
||||
@onready var services_label: Label = $Center/Panel/Contents/Services
|
||||
|
||||
var _inventory: ShipInventory
|
||||
|
||||
func _ready() -> void:
|
||||
next_button.pressed.connect(func() -> void: next_level_requested.emit())
|
||||
close_button.pressed.connect(_close)
|
||||
buy_ammunition_button.pressed.connect(_buy_ammunition)
|
||||
_inventory = get_tree().get_first_node_in_group("ship_inventory") as ShipInventory
|
||||
if _inventory:
|
||||
_inventory.ammunition_changed.connect(_refresh_ammunition_service)
|
||||
GameState.captain.changed.connect(_refresh_ammunition_service)
|
||||
_refresh_ammunition_service()
|
||||
|
||||
func show_services(at_level_cap: bool) -> void:
|
||||
_refresh_ammunition_service()
|
||||
next_button.disabled = at_level_cap
|
||||
next_button.text = "OSIĄGNIĘTO OSTATNI UKŁAD" if at_level_cap else "PRZEJDŹ DO NASTĘPNEGO UKŁADU"
|
||||
show()
|
||||
|
||||
func _refresh_ammunition_service() -> void:
|
||||
buy_ammunition_button.disabled = _inventory == null or not _inventory.can_buy_ammunition()
|
||||
if _inventory:
|
||||
buy_ammunition_button.text = "KUP %d AMUNICJI — %d KREDYTÓW" % [ShipInventory.AMMUNITION_BUY_AMOUNT, _inventory.get_ammunition_buy_cost()]
|
||||
services_label.text = "Amunicja: %d • Kredyty: %d\nCena: 100 kredytów × poziom układu (%d)" % [_inventory.ammunition, GameState.captain.credits, GameState.system_level]
|
||||
|
||||
func _buy_ammunition() -> void:
|
||||
if visible and _inventory:
|
||||
_inventory.buy_ammunition()
|
||||
|
||||
func _close() -> void:
|
||||
hide()
|
||||
closed.emit()
|
||||
|
||||
@ -6,6 +6,8 @@ const CARGO_SIZE := 20
|
||||
@onready var cargo_grid: GridContainer = $Contents/CargoGrid
|
||||
@onready var close_button: Button = $Contents/Header/CloseButton
|
||||
@onready var title_label: Label = $Contents/Header/Title
|
||||
@onready var ammunition_label: Label = $Contents/Ammunition/Count
|
||||
@onready var craft_button: Button = $Contents/Ammunition/CraftButton
|
||||
|
||||
var _inventory: ShipInventory
|
||||
var _drawer_open := false
|
||||
@ -14,9 +16,12 @@ var drawer_width := 780.0
|
||||
|
||||
func _ready() -> void:
|
||||
close_button.pressed.connect(close_drawer)
|
||||
craft_button.pressed.connect(_craft_ammunition)
|
||||
craft_button.text = "TWÓRZ +%d AMUNICJI (%.0f części)" % [ShipInventory.AMMUNITION_CRAFT_AMOUNT, ShipInventory.AMMUNITION_CRAFT_PARTS_COST]
|
||||
_inventory = get_tree().get_first_node_in_group("ship_inventory") as ShipInventory
|
||||
if _inventory:
|
||||
_inventory.inventory_changed.connect(_refresh_title)
|
||||
_inventory.ammunition_changed.connect(_refresh_title)
|
||||
GameState.captain.changed.connect(_refresh_title)
|
||||
for index in CARGO_SIZE:
|
||||
var slot := SLOT_SCENE.instantiate()
|
||||
@ -26,8 +31,14 @@ func _ready() -> void:
|
||||
_refresh_title()
|
||||
|
||||
func _refresh_title() -> void:
|
||||
craft_button.disabled = _inventory == null or not _inventory.can_craft_ammunition()
|
||||
if _inventory:
|
||||
title_label.text = "MAGAZYN (%d/%d) · Części: %.1f" % [_inventory.get_cargo_used(), CARGO_SIZE, GameState.captain.parts]
|
||||
ammunition_label.text = "AMUNICJA: %d" % _inventory.ammunition
|
||||
|
||||
func _craft_ammunition() -> void:
|
||||
if _inventory:
|
||||
_inventory.craft_ammunition()
|
||||
|
||||
func toggle_drawer() -> void:
|
||||
_set_drawer_open(not _drawer_open)
|
||||
|
||||
@ -32,7 +32,10 @@ func _ready() -> void:
|
||||
addon.stat_key = "damage_percent"
|
||||
addon.value = 10.0
|
||||
stronger.additional_modifiers.append(addon)
|
||||
assert(stronger.get_energy_cost() > cost_before_addon)
|
||||
if definition.weapon_kind == ItemDefinition.WeaponKind.MACHINE_GUN:
|
||||
assert(stronger.get_energy_cost() == 0.0)
|
||||
else:
|
||||
assert(stronger.get_energy_cost() > cost_before_addon)
|
||||
for level in [1, 50, 1000]:
|
||||
for sample in 100:
|
||||
var item := GENERATOR.generate_for_definition(definition, level)
|
||||
@ -73,6 +76,38 @@ func _ready() -> void:
|
||||
var probe := LaserProbe.new()
|
||||
player.add_child(probe)
|
||||
probe.set_physics_process(false)
|
||||
var inventory := player.get_node("ShipInventory") as ShipInventory
|
||||
assert(inventory.ammunition == 300)
|
||||
var machine_gun := ItemInstance.new()
|
||||
machine_gun.definition = preload("res://resources/items/machine_gun.tres")
|
||||
player.set("energy", 0.0)
|
||||
inventory.ammunition = 1
|
||||
assert(probe._consume_shot_resource(machine_gun))
|
||||
assert(inventory.ammunition == 0 and player.get("energy") == 0.0)
|
||||
assert(not probe._consume_shot_resource(machine_gun))
|
||||
GameState.captain.parts = 49.0
|
||||
assert(not inventory.craft_ammunition())
|
||||
assert(inventory.ammunition == 0 and GameState.captain.parts == 49.0)
|
||||
GameState.captain.parts = 50.0
|
||||
assert(inventory.craft_ammunition())
|
||||
assert(inventory.ammunition == 100 and GameState.captain.parts == 0.0)
|
||||
GameState.system_level = 3
|
||||
assert(inventory.get_ammunition_buy_cost() == 300)
|
||||
GameState.captain.credits = 299
|
||||
assert(not inventory.buy_ammunition())
|
||||
assert(inventory.ammunition == 100 and GameState.captain.credits == 299)
|
||||
GameState.captain.credits = 600
|
||||
assert(inventory.buy_ammunition())
|
||||
assert(inventory.ammunition == 200 and GameState.captain.credits == 300)
|
||||
assert(inventory.buy_ammunition())
|
||||
assert(inventory.ammunition == 300 and GameState.captain.credits == 0)
|
||||
assert(not inventory.buy_ammunition())
|
||||
GameState.system_level = 1
|
||||
inventory.preserve_for_restart()
|
||||
var restored_player := PLAYER_SCENE.instantiate() as CharacterBody2D
|
||||
add_child(restored_player)
|
||||
assert(restored_player.get_node("ShipInventory").get("ammunition") == 300)
|
||||
restored_player.queue_free()
|
||||
var target := StaticBody2D.new()
|
||||
target.position = Vector2(200, -28)
|
||||
target.collision_layer = 4
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user