Add finite prebattle shop stock
This commit is contained in:
@@ -248,34 +248,57 @@ func _is_condition_shape_valid(condition) -> bool:
|
||||
func _normalized_shop(source) -> Dictionary:
|
||||
var item_ids := []
|
||||
var seen := {}
|
||||
var stock := {}
|
||||
if typeof(source) != TYPE_DICTIONARY:
|
||||
return {"items": item_ids}
|
||||
return {"items": item_ids, "stock": stock}
|
||||
for entry in source.get("items", []):
|
||||
var item_id := ""
|
||||
if typeof(entry) == TYPE_DICTIONARY:
|
||||
item_id = str(entry.get("id", ""))
|
||||
else:
|
||||
item_id = str(entry)
|
||||
var item_id := _shop_item_id_from_entry(entry)
|
||||
if item_id.is_empty() or seen.has(item_id):
|
||||
continue
|
||||
seen[item_id] = true
|
||||
item_ids.append(item_id)
|
||||
_apply_shop_stock_entry(stock, item_id, entry)
|
||||
_apply_shop_stock_block(stock, source.get("stock", {}), seen)
|
||||
for block in source.get("conditional_items", []):
|
||||
if typeof(block) != TYPE_DICTIONARY:
|
||||
continue
|
||||
if not _campaign_flags_match(block.get("campaign_flags", {})):
|
||||
continue
|
||||
for entry in block.get("items", []):
|
||||
var item_id := ""
|
||||
if typeof(entry) == TYPE_DICTIONARY:
|
||||
item_id = str(entry.get("id", ""))
|
||||
else:
|
||||
item_id = str(entry)
|
||||
var item_id := _shop_item_id_from_entry(entry)
|
||||
if item_id.is_empty() or seen.has(item_id):
|
||||
continue
|
||||
seen[item_id] = true
|
||||
item_ids.append(item_id)
|
||||
return {"items": item_ids}
|
||||
_apply_shop_stock_entry(stock, item_id, entry)
|
||||
_apply_shop_stock_block(stock, block.get("stock", {}), seen)
|
||||
return {"items": item_ids, "stock": stock}
|
||||
|
||||
|
||||
func _shop_item_id_from_entry(entry) -> String:
|
||||
if typeof(entry) == TYPE_DICTIONARY:
|
||||
return str(entry.get("id", ""))
|
||||
return str(entry)
|
||||
|
||||
|
||||
func _apply_shop_stock_entry(stock: Dictionary, item_id: String, entry) -> void:
|
||||
if item_id.is_empty() or typeof(entry) != TYPE_DICTIONARY or not entry.has("stock"):
|
||||
return
|
||||
var count := int(entry.get("stock", -1))
|
||||
if count >= 0:
|
||||
stock[item_id] = count
|
||||
|
||||
|
||||
func _apply_shop_stock_block(stock: Dictionary, block, seen: Dictionary) -> void:
|
||||
if typeof(block) != TYPE_DICTIONARY:
|
||||
return
|
||||
for item_id in block.keys():
|
||||
var normalized_id := str(item_id)
|
||||
if normalized_id.is_empty() or not seen.has(normalized_id):
|
||||
continue
|
||||
var count := int(block[item_id])
|
||||
if count >= 0:
|
||||
stock[normalized_id] = count
|
||||
|
||||
|
||||
func _normalized_deployment_rules(source) -> Dictionary:
|
||||
@@ -1155,6 +1178,16 @@ func get_shop_item_ids() -> Array:
|
||||
return result
|
||||
|
||||
|
||||
func get_shop_stock_limit(item_id: String) -> int:
|
||||
var normalized := str(item_id)
|
||||
if normalized.is_empty():
|
||||
return -1
|
||||
var stock: Dictionary = shop.get("stock", {})
|
||||
if not stock.has(normalized):
|
||||
return -1
|
||||
return int(stock.get(normalized, -1))
|
||||
|
||||
|
||||
func get_formation_cells() -> Array[Vector2i]:
|
||||
return formation_cells.duplicate()
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ class_name CampaignState
|
||||
|
||||
const SAVE_PATH := "user://campaign_save.json"
|
||||
const MANUAL_SAVE_PATH := "user://campaign_manual_save.json"
|
||||
const SAVE_VERSION := 3
|
||||
const SAVE_VERSION := 4
|
||||
|
||||
var save_version := SAVE_VERSION
|
||||
var campaign_id := ""
|
||||
@@ -26,6 +26,7 @@ var flags := {}
|
||||
var joined_officers: Array[String] = []
|
||||
var applied_post_battle_choices := {}
|
||||
var pending_post_battle_choice_scenario_id := ""
|
||||
var shop_purchases := {}
|
||||
|
||||
|
||||
func load_campaign(path: String) -> bool:
|
||||
@@ -136,6 +137,7 @@ func start_new(scenario_id: String) -> void:
|
||||
joined_officers.clear()
|
||||
applied_post_battle_choices.clear()
|
||||
pending_post_battle_choice_scenario_id = ""
|
||||
shop_purchases.clear()
|
||||
for officer_id in initial_joined_officers:
|
||||
joined_officers.append(officer_id)
|
||||
|
||||
@@ -341,12 +343,31 @@ func get_inventory_snapshot() -> Dictionary:
|
||||
return inventory.duplicate(true)
|
||||
|
||||
|
||||
func try_buy_item(item_id: String, price: int) -> bool:
|
||||
func get_shop_purchase_count(scenario_id: String, item_id: String) -> int:
|
||||
var scenario_key := str(scenario_id)
|
||||
var item_key := str(item_id)
|
||||
if scenario_key.is_empty() or item_key.is_empty():
|
||||
return 0
|
||||
if not shop_purchases.has(scenario_key) or typeof(shop_purchases[scenario_key]) != TYPE_DICTIONARY:
|
||||
return 0
|
||||
return int(shop_purchases[scenario_key].get(item_key, 0))
|
||||
|
||||
|
||||
func try_buy_item(item_id: String, price: int, scenario_id: String = "", stock_limit: int = -1) -> bool:
|
||||
if item_id.is_empty() or price <= 0 or gold < price:
|
||||
return false
|
||||
var scenario_key := str(scenario_id)
|
||||
if stock_limit >= 0 and not scenario_key.is_empty() and get_shop_purchase_count(scenario_key, item_id) >= stock_limit:
|
||||
return false
|
||||
var previous_count := int(inventory.get(item_id, 0))
|
||||
var previous_shop_purchases: Dictionary = shop_purchases.duplicate(true)
|
||||
gold -= price
|
||||
inventory[item_id] = previous_count + 1
|
||||
if stock_limit >= 0 and not scenario_key.is_empty():
|
||||
if not shop_purchases.has(scenario_key) or typeof(shop_purchases[scenario_key]) != TYPE_DICTIONARY:
|
||||
shop_purchases[scenario_key] = {}
|
||||
var scenario_purchases: Dictionary = shop_purchases[scenario_key]
|
||||
scenario_purchases[item_id] = int(scenario_purchases.get(item_id, 0)) + 1
|
||||
if save_game():
|
||||
return true
|
||||
gold += price
|
||||
@@ -354,6 +375,7 @@ func try_buy_item(item_id: String, price: int) -> bool:
|
||||
inventory[item_id] = previous_count
|
||||
else:
|
||||
inventory.erase(item_id)
|
||||
shop_purchases = previous_shop_purchases
|
||||
return false
|
||||
|
||||
|
||||
@@ -795,7 +817,8 @@ func to_dict() -> Dictionary:
|
||||
"flags": flags.duplicate(true),
|
||||
"joined_officers": joined_officers.duplicate(),
|
||||
"applied_post_battle_choices": applied_post_battle_choices.duplicate(true),
|
||||
"pending_post_battle_choice_scenario_id": pending_post_battle_choice_scenario_id
|
||||
"pending_post_battle_choice_scenario_id": pending_post_battle_choice_scenario_id,
|
||||
"shop_purchases": shop_purchases.duplicate(true)
|
||||
}
|
||||
|
||||
|
||||
@@ -811,6 +834,7 @@ func _apply_save_data(parsed: Dictionary) -> void:
|
||||
flags = _copy_dictionary(parsed.get("flags", {}))
|
||||
applied_post_battle_choices = _copy_dictionary(parsed.get("applied_post_battle_choices", {}))
|
||||
pending_post_battle_choice_scenario_id = str(parsed.get("pending_post_battle_choice_scenario_id", ""))
|
||||
shop_purchases = _copy_dictionary(parsed.get("shop_purchases", {}))
|
||||
joined_officers.clear()
|
||||
var saved_joined = parsed.get("joined_officers", initial_joined_officers)
|
||||
for officer_id in saved_joined:
|
||||
|
||||
Reference in New Issue
Block a user