Refactor recent gameplay systems after code review
This commit is contained in:
parent
3f3a22227d
commit
d68f4d4f88
57 changed files with 530 additions and 572 deletions
120
GameState.gd
120
GameState.gd
|
|
@ -387,7 +387,11 @@ func prerequisite_met(id: String) -> bool:
|
|||
func can_unlock(id: String) -> bool:
|
||||
var node: Dictionary = skill_node(id)
|
||||
return not is_unlocked(id) and prerequisite_met(id) and can_afford(int(node.cost)) \
|
||||
and research_points >= int(node.get("research_points", 0))
|
||||
and research_points >= skill_research_point_cost(id)
|
||||
|
||||
|
||||
func skill_research_point_cost(id: String) -> int:
|
||||
return int(skill_node(id).get("research_points", 0))
|
||||
|
||||
|
||||
func unlock(id: String) -> bool:
|
||||
|
|
@ -396,7 +400,7 @@ func unlock(id: String) -> bool:
|
|||
var node: Dictionary = skill_node(id)
|
||||
if not spend(int(node.cost)):
|
||||
return false
|
||||
var points_needed: int = int(node.get("research_points", 0))
|
||||
var points_needed: int = skill_research_point_cost(id)
|
||||
if points_needed > 0:
|
||||
research_points -= points_needed
|
||||
research_points_changed.emit(research_points)
|
||||
|
|
@ -446,6 +450,8 @@ func reset_new_game() -> void:
|
|||
planet_id = ""
|
||||
planet_definition_id = "rocky"
|
||||
fleet_speed_multiplier = 1.0
|
||||
_distorder_drain_progress = 0.0
|
||||
boost_depleted_notice = false
|
||||
research_points = 0
|
||||
explored_chunks.clear()
|
||||
bank_inventory = INVENTORY.new({RESOURCE_ORE: 500})
|
||||
|
|
@ -520,6 +526,13 @@ func building_has_capability(building: Dictionary, capability: String) -> bool:
|
|||
return definition != null and capability in definition.capabilities
|
||||
|
||||
|
||||
func building_logistics_profile(building: Dictionary) -> Resource:
|
||||
if building.is_empty():
|
||||
return null
|
||||
var definition: Resource = BUILDING_DEFINITIONS.get_definition(String(building.type))
|
||||
return null if definition == null else definition.logistics
|
||||
|
||||
|
||||
# --- vessel types and their upgrades (#5) ---------------------------------
|
||||
|
||||
# Combat vessels can join the player fleet. Transporter metadata lives in the
|
||||
|
|
@ -1044,19 +1057,20 @@ func has_building_of_type(type: String) -> bool:
|
|||
|
||||
func remove_buildings_of_type(type: String) -> int:
|
||||
var kept: Array = []
|
||||
var removed_ids: Array = []
|
||||
var removed_hub_ids: Array = []
|
||||
var removed: int = 0
|
||||
for b in buildings:
|
||||
if b.type == type:
|
||||
removed += 1
|
||||
removed_ids.append(int(b.id))
|
||||
if building_has_capability(b, "transport_hub"):
|
||||
removed_hub_ids.append(int(b.id))
|
||||
else:
|
||||
kept.append(b)
|
||||
buildings = kept
|
||||
if type == BUILDING_TRANSPORT_HUB and not removed_ids.is_empty():
|
||||
if not removed_hub_ids.is_empty():
|
||||
var kept_transporters: Array = []
|
||||
for transporter in transporters:
|
||||
if int(transporter.get("hub_id", 0)) not in removed_ids:
|
||||
if int(transporter.get("hub_id", 0)) not in removed_hub_ids:
|
||||
kept_transporters.append(transporter)
|
||||
transporters = kept_transporters
|
||||
return removed
|
||||
|
|
@ -1186,44 +1200,50 @@ func _extractor_inventory(extractor: Dictionary) -> RefCounted:
|
|||
return inventory
|
||||
|
||||
|
||||
# --- gas burners (#54) -----------------------------------------------------
|
||||
#
|
||||
# Converts gas into energy at the building's own site, simulated here
|
||||
# alongside extractor mining and production so it keeps running whether or
|
||||
# not the player is nearby. Deliberately withdraws only from the building's
|
||||
# OWN inventory, never the bank - a burner with no local gas simply stalls,
|
||||
# exactly like a lab or crafter waiting on materials, rather than conjuring
|
||||
# energy for free.
|
||||
# --- building logistics and resource conversion ---------------------------
|
||||
|
||||
const GAS_BURN_RATE: float = 1.0 # gas/second
|
||||
const ENERGY_PER_GAS: int = 2
|
||||
# Local gas reserve a burner tries to keep topped up. Transporters treat
|
||||
# falling short of this the same way they treat a queued production/research
|
||||
# order (see _dispatch_transporters()'s gas_burner_gas_deficit() use).
|
||||
const GAS_BURNER_BUFFER: int = 40
|
||||
|
||||
|
||||
func gas_burner_gas_deficit(id: int) -> int:
|
||||
var b: Dictionary = find_building(id)
|
||||
if not building_has_capability(b, "gas_burner"):
|
||||
func building_logistics_deficit(id: int, resource_type: String) -> int:
|
||||
var building: Dictionary = find_building(id)
|
||||
var profile: Resource = building_logistics_profile(building)
|
||||
if profile == null:
|
||||
return 0
|
||||
return maxi(0, GAS_BURNER_BUFFER - building_resource(id, RESOURCE_GAS))
|
||||
var target: int = int(profile.input_buffers.get(resource_type, 0))
|
||||
return maxi(0, target - building_resource(id, resource_type))
|
||||
|
||||
|
||||
func _advance_gas_burners(delta: float) -> void:
|
||||
for b in buildings:
|
||||
if not building_has_capability(b, "gas_burner"):
|
||||
func building_requested_resource(id: int, resource_type: String) -> int:
|
||||
return maxi(outstanding_resource_cost(id, resource_type),
|
||||
building_logistics_deficit(id, resource_type))
|
||||
|
||||
|
||||
func _collectable_building_resource(building: Dictionary, minimum_amount: int) -> String:
|
||||
var profile: Resource = building_logistics_profile(building)
|
||||
if profile == null:
|
||||
return ""
|
||||
for resource_type in profile.collected_outputs:
|
||||
if building_resource(int(building.id), resource_type) >= minimum_amount:
|
||||
return resource_type
|
||||
return ""
|
||||
|
||||
|
||||
func _advance_resource_converters(delta: float) -> void:
|
||||
for building in buildings:
|
||||
var profile: Resource = building_logistics_profile(building)
|
||||
if profile == null or profile.conversion_input == "" \
|
||||
or profile.conversion_output == "" or profile.conversion_rate <= 0.0 \
|
||||
or profile.conversion_yield <= 0:
|
||||
continue
|
||||
var inventory: RefCounted = _inventory_for_record(b)
|
||||
if inventory.amount(RESOURCE_GAS) <= 0:
|
||||
continue # stalled - no local gas to burn
|
||||
var progress: float = float(b.get("gas_burn_progress", 0.0)) + delta * GAS_BURN_RATE
|
||||
var whole: int = mini(int(floor(progress)), inventory.amount(RESOURCE_GAS))
|
||||
var inventory: RefCounted = _inventory_for_record(building)
|
||||
if inventory.amount(profile.conversion_input) <= 0:
|
||||
continue
|
||||
var progress: float = float(building.get("conversion_progress", 0.0)) \
|
||||
+ delta * profile.conversion_rate
|
||||
var whole: int = mini(int(floor(progress)), inventory.amount(profile.conversion_input))
|
||||
if whole > 0:
|
||||
inventory.withdraw(RESOURCE_GAS, whole)
|
||||
inventory.deposit(RESOURCE_ENERGY, whole * ENERGY_PER_GAS)
|
||||
inventory.withdraw(profile.conversion_input, whole)
|
||||
inventory.deposit(profile.conversion_output, whole * profile.conversion_yield)
|
||||
progress -= whole
|
||||
b.gas_burn_progress = progress
|
||||
building.conversion_progress = progress
|
||||
|
||||
|
||||
func _advance_distorder_drain(delta: float) -> void:
|
||||
|
|
@ -1341,7 +1361,7 @@ func _process(delta: float) -> void:
|
|||
_advance_production(delta)
|
||||
_advance_lab_research(delta)
|
||||
_advance_vessel_deliveries(delta)
|
||||
_advance_gas_burners(delta)
|
||||
_advance_resource_converters(delta)
|
||||
_advance_distorder_drain(delta)
|
||||
for e in extractors:
|
||||
e.mining_progress = float(e.get("mining_progress", 0.0)) + delta * EXTRACTOR_RATE
|
||||
|
|
@ -1500,13 +1520,7 @@ func _dispatch_transporters() -> void:
|
|||
for b in buildings:
|
||||
var needed_resource := ""
|
||||
for resource_type in resource_types():
|
||||
# A gas burner's ongoing gas deficit is folded in alongside
|
||||
# queued production/research costs (#54) - both are just "this
|
||||
# building wants more of resource_type", so the one dispatch
|
||||
# path already below serves both without any new transporter
|
||||
# state.
|
||||
var need: int = maxi(outstanding_resource_cost(int(b.id), resource_type),
|
||||
gas_burner_gas_deficit(int(b.id)) if resource_type == RESOURCE_GAS else 0)
|
||||
var need: int = building_requested_resource(int(b.id), resource_type)
|
||||
if need > 0 and bank_inventory.amount(resource_type) > 0:
|
||||
needed_resource = resource_type
|
||||
break
|
||||
|
|
@ -1559,14 +1573,11 @@ func _dispatch_transporters() -> void:
|
|||
_begin_leg(chosen_extractor, transporter_position(chosen_extractor), extractor.position,
|
||||
TRANSPORTER_TO_EXTRACTOR)
|
||||
|
||||
# Collecting a gas burner's energy output, last: queued deliveries and
|
||||
# extractor collection both outrank it, same "supply what's needed
|
||||
# before what's merely ready" ordering _dispatch_transporters() already
|
||||
# holds for extractors over queued orders (f5c60f8).
|
||||
# Collect building outputs last: queued deliveries and extractor collection
|
||||
# both outrank resources that are merely ready for pickup.
|
||||
for b in buildings:
|
||||
if not building_has_capability(b, "gas_burner"):
|
||||
continue
|
||||
if building_resource(int(b.id), RESOURCE_ENERGY) < load or _transporter_inbound_for_pickup(int(b.id)):
|
||||
var pickup_resource: String = _collectable_building_resource(b, load)
|
||||
if pickup_resource == "" or _transporter_inbound_for_pickup(int(b.id)):
|
||||
continue
|
||||
var chosen_pickup: Dictionary = {}
|
||||
var best_pickup_distance: float = INF
|
||||
|
|
@ -1580,7 +1591,7 @@ func _dispatch_transporters() -> void:
|
|||
if chosen_pickup.is_empty():
|
||||
return
|
||||
chosen_pickup.target_id = int(b.id)
|
||||
chosen_pickup.resource_type = RESOURCE_ENERGY
|
||||
chosen_pickup.resource_type = pickup_resource
|
||||
chosen_pickup.extractor_index = -1
|
||||
_begin_leg(chosen_pickup, transporter_position(chosen_pickup), b.position,
|
||||
TRANSPORTER_TO_BUILDING_PICKUP)
|
||||
|
|
@ -1610,8 +1621,7 @@ func _arrive(t: Dictionary) -> void:
|
|||
TRANSPORTER_TO_MOTHERSHIP:
|
||||
var target: Dictionary = find_building(int(t.target_id))
|
||||
var resource_type: String = String(t.get("resource_type", RESOURCE_ORE))
|
||||
var want: int = maxi(outstanding_resource_cost(int(t.target_id), resource_type),
|
||||
gas_burner_gas_deficit(int(t.target_id)) if resource_type == RESOURCE_GAS else 0)
|
||||
var want: int = building_requested_resource(int(t.target_id), resource_type)
|
||||
var take: int = mini(mini(want, bank_inventory.amount(resource_type)), transporter_load_limit())
|
||||
if take <= 0 or target.is_empty():
|
||||
# Nothing to carry, or the building is gone. Go home empty.
|
||||
|
|
|
|||
Loading…
Reference in a new issue