Resolve pending gameplay tickets
This commit is contained in:
parent
ec20778215
commit
c2ebbfaa2d
28 changed files with 618 additions and 188 deletions
|
|
@ -657,10 +657,10 @@ func skill_costs(id: String) -> Dictionary:
|
|||
return {RESOURCE_ORE: int(node.cost)} if int(node.cost) > 0 else {}
|
||||
|
||||
|
||||
func can_unlock(id: String) -> bool:
|
||||
func can_unlock(id: String, payment_position: Variant = null) -> bool:
|
||||
var node: Dictionary = skill_node(id)
|
||||
return not is_unlocked(id) and prerequisite_met(id) \
|
||||
and can_afford_resources(skill_costs(id)) \
|
||||
and can_afford_resources(skill_costs(id), payment_position) \
|
||||
and research_points >= skill_research_point_cost(id)
|
||||
|
||||
|
||||
|
|
@ -668,11 +668,11 @@ func skill_research_point_cost(id: String) -> int:
|
|||
return int(skill_node(id).get("research_points", 0))
|
||||
|
||||
|
||||
func unlock(id: String) -> bool:
|
||||
if not can_unlock(id):
|
||||
func unlock(id: String, payment_position: Variant = null) -> bool:
|
||||
if not can_unlock(id, payment_position):
|
||||
return false
|
||||
var node: Dictionary = skill_node(id)
|
||||
if not spend_resources(skill_costs(id)):
|
||||
if not spend_resources(skill_costs(id), payment_position):
|
||||
return false
|
||||
var points_needed: int = skill_research_point_cost(id)
|
||||
if points_needed > 0:
|
||||
|
|
@ -1314,13 +1314,13 @@ func vessel_for_unlock(unlock_id: String) -> Resource:
|
|||
return null
|
||||
|
||||
|
||||
func unlock_vessel(vessel: String) -> bool:
|
||||
func unlock_vessel(vessel: String, payment_position: Variant = null) -> bool:
|
||||
var definition: Resource = vessel_definition(vessel)
|
||||
if definition == null or definition.unlock_id == "" or vessel_is_unlocked(vessel) or not has_ship_lab():
|
||||
return false
|
||||
var costs: Dictionary = research_costs(definition.unlock_id)
|
||||
var points_needed: int = int(definition.research_point_cost)
|
||||
if research_points < points_needed or not spend_resources(costs):
|
||||
if research_points < points_needed or not spend_resources(costs, payment_position):
|
||||
return false
|
||||
if points_needed > 0:
|
||||
research_points -= points_needed
|
||||
|
|
@ -1370,15 +1370,16 @@ func upgrade_cost(id: String) -> int:
|
|||
return int(d.cost) * (upgrade_level(id) + 1)
|
||||
|
||||
|
||||
func can_buy_upgrade(id: String) -> bool:
|
||||
return has_ship_lab() and not upgrade_maxed(id) and can_afford(upgrade_cost(id)) \
|
||||
func can_buy_upgrade(id: String, payment_position: Variant = null) -> bool:
|
||||
return has_ship_lab() and not upgrade_maxed(id) \
|
||||
and can_afford(upgrade_cost(id), payment_position) \
|
||||
and research_points >= research_point_cost(id)
|
||||
|
||||
|
||||
func buy_upgrade(id: String) -> bool:
|
||||
if not can_buy_upgrade(id):
|
||||
func buy_upgrade(id: String, payment_position: Variant = null) -> bool:
|
||||
if not can_buy_upgrade(id, payment_position):
|
||||
return false
|
||||
if not spend(upgrade_cost(id)):
|
||||
if not spend(upgrade_cost(id), payment_position):
|
||||
return false
|
||||
var points_needed: int = research_point_cost(id)
|
||||
if points_needed > 0:
|
||||
|
|
@ -1601,7 +1602,12 @@ const LOCAL_PAY_RANGE: float = 150.0
|
|||
func fleet_is_at(building: Dictionary) -> bool:
|
||||
if building.is_empty():
|
||||
return false
|
||||
return fleet_position.distance_to(building.position) <= LOCAL_PAY_RANGE
|
||||
return fleet_can_pay_at(building.position)
|
||||
|
||||
|
||||
func fleet_can_pay_at(payment_position: Variant) -> bool:
|
||||
return payment_position is Vector2 \
|
||||
and fleet_position.distance_to(payment_position as Vector2) <= LOCAL_PAY_RANGE
|
||||
|
||||
|
||||
func local_payment_available(building: Dictionary, inventory: RefCounted,
|
||||
|
|
@ -3332,10 +3338,10 @@ func _advance_quests() -> void:
|
|||
|
||||
# --- paying for things ------------------------------------------------------
|
||||
#
|
||||
# EVERY payment draws on the bank AND on what the ships are carrying. The
|
||||
# player can already move resources between the two by hand at any building
|
||||
# that takes them, so refusing a purchase that a couple of taps would have
|
||||
# made affordable was pure ceremony.
|
||||
# Payments draw on the bank and may also draw on what the ships are carrying
|
||||
# when the caller supplies the concrete place being paid. The player can move
|
||||
# resources between the two by hand, so using nearby cargo avoids ceremony;
|
||||
# #180 makes "nearby" part of the API instead of an assumption in the caller.
|
||||
#
|
||||
# In one case it was worse than ceremony. A fresh game starts with an empty
|
||||
# bank, ore is mined into the fleet hold, and the only way to bank it is to
|
||||
|
|
@ -3343,9 +3349,8 @@ func _advance_quests() -> void:
|
|||
# made the first mothership cost ore that could not yet exist. Mine forever,
|
||||
# build nothing.
|
||||
#
|
||||
# Bank first, hold second. The hold is also the fleet's mining capacity, so
|
||||
# leaving it as full as possible means the next trip out can still carry
|
||||
# something back.
|
||||
# Bank first, nearby hold second. A call with no position is deliberately
|
||||
# bank-only: missing context must fail safe instead of teleporting cargo.
|
||||
#
|
||||
# The one deliberate exception is AMMO - see AimedFleetAbilityController,
|
||||
# which checks fleet_resource() directly. A gas bomb is fired from what the
|
||||
|
|
@ -3357,36 +3362,50 @@ func available_resource(resource_type: String) -> int:
|
|||
return bank_inventory.amount(resource_type) + fleet_inventory.amount(resource_type)
|
||||
|
||||
|
||||
# What can pay at one concrete place. Banked resources remain globally
|
||||
# available; cargo in the fleet hold joins them only when the fleet is close
|
||||
# enough to physically hand it to the building or construction site (#180).
|
||||
# A null position deliberately means "no local payer", so a forgotten context
|
||||
# can never reach into the hold from across the map.
|
||||
func available_resource_at(resource_type: String, payment_position: Variant = null) -> int:
|
||||
var amount: int = bank_inventory.amount(resource_type)
|
||||
if fleet_can_pay_at(payment_position):
|
||||
amount += fleet_inventory.amount(resource_type)
|
||||
return amount
|
||||
|
||||
|
||||
func available_ore() -> int:
|
||||
return available_resource(RESOURCE_ORE)
|
||||
|
||||
|
||||
func can_afford(cost: int) -> bool:
|
||||
return available_ore() >= cost
|
||||
func can_afford(cost: int, payment_position: Variant = null) -> bool:
|
||||
return available_resource_at(RESOURCE_ORE, payment_position) >= cost
|
||||
|
||||
|
||||
func can_afford_resources(costs: Dictionary) -> bool:
|
||||
func can_afford_resources(costs: Dictionary, payment_position: Variant = null) -> bool:
|
||||
for resource_type in costs:
|
||||
if available_resource(String(resource_type)) < int(costs[resource_type]):
|
||||
if available_resource_at(String(resource_type), payment_position) \
|
||||
< int(costs[resource_type]):
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
func spend(cost: int) -> bool:
|
||||
return spend_resources({RESOURCE_ORE: cost})
|
||||
func spend(cost: int, payment_position: Variant = null) -> bool:
|
||||
return spend_resources({RESOURCE_ORE: cost}, payment_position)
|
||||
|
||||
|
||||
func spend_resources(costs: Dictionary) -> bool:
|
||||
func spend_resources(costs: Dictionary, payment_position: Variant = null) -> bool:
|
||||
# Affordability is settled in full BEFORE anything is taken. Charging for
|
||||
# part of a purchase that then fails is worse than refusing it, and with
|
||||
# several resource types in one price that is a real possibility rather
|
||||
# than a theoretical one.
|
||||
if not can_afford_resources(costs):
|
||||
if not can_afford_resources(costs, payment_position):
|
||||
return false
|
||||
var fleet_can_pay: bool = fleet_can_pay_at(payment_position)
|
||||
for resource_type in costs:
|
||||
var id: String = String(resource_type)
|
||||
var owed: int = int(costs[resource_type])
|
||||
owed -= bank_inventory.withdraw(id, owed)
|
||||
if owed > 0:
|
||||
if owed > 0 and fleet_can_pay:
|
||||
fleet_inventory.withdraw(id, owed)
|
||||
return true
|
||||
|
|
|
|||
Loading…
Reference in a new issue