extends Control var base @onready var ship = get_tree().current_scene.ship @onready var sell_list = $TradingMenu/SellList @onready var buy_list = $TradingMenu/BuyList @onready var main_menu_header = $MainMenu/Header @onready var sell_input = $TradingMenu/SellInput @onready var buy_input = $TradingMenu/BuyInput @onready var sell_button = $TradingMenu/SellButton @onready var buy_button = $TradingMenu/BuyButton @onready var current_quest_status = $QuestMenu/CurrentQuest/QuestStatus @onready var abandon_quest = $QuestMenu/CurrentQuest/AbandonQuest @onready var complete_quest = $QuestMenu/CurrentQuest/CompleteQuest @onready var current_quest = $QuestMenu/CurrentQuest @onready var new_quest = $QuestMenu/NewQuest @onready var accept_quest = $QuestMenu/NewQuest/AcceptQuest @onready var new_quest_status = $QuestMenu/NewQuest/QuestStatus @onready var available_modules = $EquipmentMenu/AvailableItems @onready var buyable_modules = $EquipmentMenu/BuyableItems @onready var select_hull = $EquipmentMenu/HullSelect @onready var select_engine = $EquipmentMenu/EngineSelect @onready var select_shield = $EquipmentMenu/ShieldSelect @onready var select_weapon = $EquipmentMenu/WeaponSelect @onready var buy_sell_mod = $EquipmentMenu/BuySellButton @onready var equip_mod = $EquipmentMenu/EquipButton @onready var equip_primary = $EquipmentMenu/EquipPrimaryButton @onready var equip_secondary = $EquipmentMenu/EquipSecondaryButton @onready var label_mod_info = $EquipmentMenu/LabelInfoBlock var base_types = ["Power Supply", "Mining", "Food Production", "Trading"] var equipment_category = "hull" var focused_mod_id = -1 var focused_list = null var available_hulls : Array[String] var available_engines : Array[String] var available_shields : Array[String] var available_weapons : Array[String] var hulls_prices : Dictionary var engines_prices : Dictionary var shields_prices : Dictionary var weapons_prices : Dictionary var available_list : Array[String] = [] var buyable_list : Array[String] = [] func _ready(): update_lists() main_menu_header.text = "{BaseType} Station".format({"BaseType" : base_types[base.type]}) buy_button.button_up.connect(buy_item) sell_button.button_up.connect(sell_item) buy_input.text_changed.connect(buy_text_changed) sell_input.text_changed.connect(sell_text_changed) abandon_quest.button_up.connect(quest_abandon) complete_quest.button_up.connect(quest_complete) accept_quest.button_up.connect(quest_accept) select_hull.button_up.connect(select_hull_mod) select_engine.button_up.connect(select_engine_mod) select_shield.button_up.connect(select_shield_mod) select_weapon.button_up.connect(select_weapon_mod) buy_sell_mod.button_up.connect(buy_or_sell_mod) equip_mod.button_up.connect(equip_module) equip_primary.button_up.connect(equip_weapon_primary) equip_secondary.button_up.connect(equip_weapon_secondary) available_modules.item_clicked.connect(available_mod_focus) buyable_modules.item_clicked.connect(buyable_mod_focus) available_modules.empty_clicked.connect(modules_list_empty_click) buyable_modules.empty_clicked.connect(modules_list_empty_click) quest_status_update() buy_sell_mod.disabled = true equip_mod.disabled = true equip_primary.disabled = true equip_secondary.disabled = true available_hulls = base.available_hulls available_engines = base.available_engines available_shields = base.available_shields available_weapons = base.available_weapons hulls_prices = base.hulls_prices engines_prices = base.engines_prices shields_prices = base.shields_prices weapons_prices = base.weapons_prices select_hull_mod() ## Updates buy and sell list in trading menu with available items func update_lists(): buy_list.clear() sell_list.clear() for i in range(len(base.want_to_buy)): var format = { "name" : base.want_to_buy[i].name, "price" : base.buy_prices[i] } var buy_text = "{name} -> {price} MU".format(format) buy_list.add_item(buy_text, base.want_to_buy[i].icon) for i in range(len(base.want_to_sell)): var format = { "name" : base.want_to_sell[i].name, "price" : base.sell_prices[i] } var sell_text = "{name} <- {price} MU".format(format) sell_list.add_item(sell_text, base.want_to_sell[i].icon) ## Event handler for buy option in trading menu func buy_item(): var amount = int(sell_input.text) amount = clamp(amount, 0, amount) if amount <= 0: sell_input.text = "" sell_input.placeholder_text = "Wrong amount!" return if len(sell_list.get_selected_items()) == 0: sell_input.text = "" sell_input.placeholder_text = "Item not chosen!" return var item_data = sell_list.get_item_text(sell_list.get_selected_items()[0]).split(" <- ") var price = float(item_data[1]) var total_price = price * amount if total_price > ship.money: sell_input.text = "" sell_input.placeholder_text = "Insufficient funds!" return if ship.hull.cargo.has(item_data[0]): ship.hull.cargo[item_data[0]] += amount else: ship.hull.cargo[item_data[0]] = amount ship.money -= total_price print(ship.hull.cargo) ## Event handler for sell option in trading menu func sell_item(): if len(buy_list.get_selected_items()) == 0: buy_input.text = "" buy_input.placeholder_text = "Item not chosen!" return var item_data = buy_list.get_item_text(buy_list.get_selected_items()[0]).split(" -> ") if !ship.hull.cargo.has(item_data[0]): buy_input.text = "" buy_input.placeholder_text = "No such item in cargo!" return var price = float(item_data[1]) var amount = int(buy_input.text) var total_price = price * amount amount = clamp(amount, 0, amount) if amount <= 0: buy_input.text = "" buy_input.placeholder_text = "Wrong amount!" return if amount > ship.hull.cargo[item_data[0]]: buy_input.text = "" buy_input.placeholder_text = "Can't sell more than have!" return ship.hull.cargo[item_data[0]] -= amount ship.money += total_price print(ship.hull.cargo) func buy_text_changed(_new_text): buy_input.placeholder_text = "Amount to sell" func sell_text_changed(_new_text): sell_input.placeholder_text = "Amount to buy" ## Event handler for abandoning in active quest menu func quest_abandon(): ship.quest.fail() current_quest.visible = false new_quest.visible = true quest_status_update() ## Event handler for completion in active quest menu func quest_complete(): if !ship.quest_completed: return ship.money += ship.quest.reward_money ship.quest_completed = false current_quest.visible = false new_quest.visible = true quest_status_update() ## Event handler for acception in new quest menu func quest_accept(): ship.quest.create(base.quest.type, base.quest.progress_max, base.quest.reward_money, base.quest.restrictions, base.quest.data) ship.quest.progress = 0 new_quest.visible = false current_quest.visible = true quest_status_update() ## Updates text in quest menu, either new or active func quest_status_update(): var ship_has_quest = !ship.quest.new or ship.quest_completed var upd_quest = ship.quest if ship_has_quest else base.quest var upd_text = current_quest_status if ship_has_quest else new_quest_status var restriction_typing = { Quest.RESTRICTIONS.NO_DEATHS : '- Destruction of your ship will lead to quest failure.', Quest.RESTRICTIONS.NO_WEAPON : '- Using any weapon (even accidently) is prohibited.', Quest.RESTRICTIONS.TIMER : '- You have {sec} seconds to complete the quest.' } if upd_quest.data.has('timer'): restriction_typing[Quest.RESTRICTIONS.TIMER] = restriction_typing[Quest.RESTRICTIONS.TIMER].format({"sec" : upd_quest.data['timer']}) var template = "Type: {type}\n\nObjective: {objective_text}\n\nReward: {reward} money units\n\nRestrictions: {restrictions}" var typed_templates = { Quest.TYPE.ELIMINATION : { "type" : "Elimination", "objective" : "Destroy {req} hostile ships [ {cur} / {req} ]".format({"cur" : upd_quest.progress, "req" : upd_quest.progress_max}) }, Quest.TYPE.DELIVERY : { "type" : "Delivery", "objective" : "Deliver a cargo to markered base (check the minimap)." } } var restrictions = "" if len(upd_quest.restrictions) == 0 : restrictions = "None" else: for restriction in upd_quest.restrictions: restrictions += "\n" + restriction_typing[restriction] var formatting = { "type" : typed_templates[upd_quest.type]['type'], "objective_text" : typed_templates[upd_quest.type]['objective'], "reward" : upd_quest.reward_money, "restrictions" : restrictions } upd_text.text = template.format(formatting) complete_quest.disabled = !ship.quest_completed ## Hull selection in equipment menu func select_hull_mod(): equipment_category = "hull" select_hull.disabled = true select_engine.disabled = false select_shield.disabled = false select_weapon.disabled = false available_modules.clear() buyable_modules.clear() available_list = available_hulls.filter(func(index): return ship.hulls.has(index)) buyable_list = available_hulls.filter(func(index): return !ship.hulls.has(index)) add_available(available_list) add_buyable(buyable_list) ## Engine selection in equipment menu func select_engine_mod(): equipment_category = "engine" select_hull.disabled = false select_engine.disabled = true select_shield.disabled = false select_weapon.disabled = false available_modules.clear() buyable_modules.clear() available_list = available_engines.filter(func(index): return ship.engines.has(index)) buyable_list = available_engines.filter(func(index): return !ship.engines.has(index)) add_available(available_list) add_buyable(buyable_list) ## Shield selection in equipment menu func select_shield_mod(): equipment_category = "shield" select_hull.disabled = false select_engine.disabled = false select_shield.disabled = true select_weapon.disabled = false available_modules.clear() buyable_modules.clear() available_list = available_shields.filter(func(index): return ship.shields.has(index)) buyable_list = available_shields.filter(func(index): return !ship.shields.has(index)) add_available(available_list) add_buyable(buyable_list) ## Weapon selection in equipment menu func select_weapon_mod(): equipment_category = "weapon" select_hull.disabled = false select_engine.disabled = false select_shield.disabled = false select_weapon.disabled = true available_modules.clear() buyable_modules.clear() available_list = available_weapons.filter(func(index): return ship.weapons.has(index)) buyable_list = available_weapons.filter(func(index): return !ship.weapons.has(index)) add_available(available_list) add_buyable(buyable_list) func add_available(avail_list): if len(avail_list) < 1: return for i in range(len(avail_list)): var meta = { 'type' : equipment_category, 'item' : avail_list[i], 'equipped' : false, 'primary' : false, 'secondary' : false } match equipment_category: 'hull': meta['price'] = hulls_prices[avail_list[i]] meta['equipped'] = ship.hull.id == avail_list[i] print(ship.hull.id, avail_list[i]) 'engine': meta['price'] = engines_prices[avail_list[i]] meta['equipped'] = ship.engine.id == avail_list[i] 'shield': meta['price'] = shields_prices[avail_list[i]] meta['equipped'] = ship.shield.id == avail_list[i] 'weapon': meta['price'] = weapons_prices[avail_list[i]] meta['primary'] = ship.primary_slot.get_child(0).id == avail_list[i] meta['secondary'] = ship.secondary_slot.get_child(0).id == avail_list[i] var embed = { 'prefix' : '', 'name' : Game.get_item(avail_list[i]).name, 'price' : meta['price'] } if meta['equipped']: embed['prefix'] = '(Equipped) ' elif meta['primary'] and !meta['secondary']: embed['prefix'] = '(Primary) ' elif meta['secondary'] and !meta['primary']: embed['prefix'] = '(Secondary) ' elif meta['primary'] and meta['secondary']: embed['prefix'] = '(Both) ' var text = "{prefix}{name} -> {price} MU".format(embed) available_modules.add_item(text) available_modules.set_item_metadata(i, meta) func add_buyable(buy_list): if len(buy_list) < 1: return for i in range(len(buy_list)): var meta = { 'type' : equipment_category, 'item' : buy_list[i], 'equipped' : false, 'primary' : false, 'secondary' : false } match equipment_category: 'hull': meta['price'] = hulls_prices[buy_list[i]] 'engine': meta['price'] = engines_prices[buy_list[i]] 'shield': meta['price'] = shields_prices[buy_list[i]] 'weapon': meta['price'] = weapons_prices[buy_list[i]] var embed = { 'name' : Game.get_item(buy_list[i]).name, 'price' : meta['price'] } var text = "{name} -> {price} MU".format(embed) buyable_modules.add_item(text) buyable_modules.set_item_metadata(i, meta) ## Available modules focused in equipment menu func available_mod_focus(index : int, _at, _mouse): var meta = available_modules.get_item_metadata(index) if equipment_category == "weapon": buy_sell_mod.disabled = meta['primary'] or meta['secondary'] equip_mod.disabled = true equip_primary.disabled = meta['primary'] equip_secondary.disabled = meta['secondary'] else: buy_sell_mod.disabled = meta['equipped'] equip_mod.disabled = meta['equipped'] equip_primary.disabled = true equip_secondary.disabled = true focused_mod_id = index focused_list = available_modules set_module_info_text(meta['item']) ## Buyable modules focused in equipment menu func buyable_mod_focus(index : int, _at, _mouse): var meta = buyable_modules.get_item_metadata(index) buy_sell_mod.disabled = ship.money < meta['price'] equip_mod.disabled = true equip_primary.disabled = true equip_secondary.disabled = true focused_mod_id = index focused_list = buyable_modules set_module_info_text(meta['item']) ## Disable all actions with modules cuz it's not focused in equipment menu func mod_unfocus(): buy_sell_mod.disabled = true equip_mod.disabled = true equip_primary.disabled = true equip_secondary.disabled = true label_mod_info.text = "Select a module to receive info about it." func modules_list_empty_click(_at, _mouse): mod_unfocus() func buy_module(): var meta = buyable_modules.get_item_metadata(buyable_modules.get_selected_items()[0]) var price = meta['price'] var item = meta['item'] if ship.money < price: return ship.money -= price match equipment_category: 'hull': ship.hulls.append(item) select_hull_mod() 'engine': ship.engines.append(item) select_engine_mod() 'shield': ship.shields.append(item) select_shield_mod() 'weapon': ship.weapons.append(item) select_weapon_mod() func sell_module(): var meta = available_modules.get_item_metadata(available_modules.get_selected_items()[0]) if meta['equipped'] or meta['primary'] or meta['secondary']: return var price = meta['price'] var item = meta['item'] ship.money += price match equipment_category: 'hull': ship.hulls.erase(item) select_hull_mod() 'engine': ship.engines.erase(item) select_engine_mod() 'shield': ship.shields.erase(item) select_shield_mod() 'weapon': ship.weapons.erase(item) select_weapon_mod() func buy_or_sell_mod(): if equip_mod.disabled and equip_primary.disabled: buy_module() return sell_module() mod_unfocus() func equip_module(): var meta = available_modules.get_item_metadata(available_modules.get_selected_items()[0]) match equipment_category: 'hull': ship.change_hull(meta['item']) select_hull_mod() 'engine': ship.change_engine(meta['item']) select_engine_mod() 'shield': ship.change_shield(meta['item']) select_shield_mod() mod_unfocus() func equip_weapon_primary(): var meta = available_modules.get_item_metadata(available_modules.get_selected_items()[0]) ship.change_primary_weapon(meta['item']) get_tree().create_timer(0.05).timeout.connect(select_weapon_mod) mod_unfocus() func equip_weapon_secondary(): var meta = available_modules.get_item_metadata(available_modules.get_selected_items()[0]) ship.change_secondary_weapon(meta['item']) get_tree().create_timer(0.05).timeout.connect(select_weapon_mod) mod_unfocus() func set_module_info_text(item): var itm = Game.get_item(item) var module var format if equipment_category == "weapon": module = Game.get_weapon(item).instantiate() else: module = Game.get_module(item, equipment_category).instantiate() var text = "{description}\nStats:\n".format({'description':itm.description}) match equipment_category: 'hull': format = { 'maxhp' : module.max_hp, 'maxfuel' : module.max_fuel, 'maxcargo' : module.max_weight } text += "Max strength: {maxhp} HS\nFuel capacity: {maxfuel} FU\nCargo weight: {maxcargo} WU".format(format) 'engine': format = { 'maxspeed' : module.max_speed, 'maxturbo' : module.max_turbo_speed, 'acceleration' : module.acceleration, 'fuelcons' : module.fuel_consumption, 'rotation' : module.rotation_speed } text += "Max speed (normal): {maxspeed} MU/sec\nMax speed (turbo): {maxturbo} MU/sec\nAcceleration: {acceleration} MU/sec\nFuel consumption: {fuelcons} FU/sec\nRotation speed: {rotation} deg/sec".format(format) 'shield': format = { 'maxcap' : module.max_capacity, 'recharge' : module.shield_charge_rate, 'delay' : module.recharge_timer.wait_time, 'laser' : module.laser_charge_rate } text += "Max capacity: {maxcap} SU\nСharge rate: {recharge} SU/sec\nRecharge delay: {delay} seconds\nLaser Сharge rate: {las} LE/sec".format(format) 'weapon': format = { 'spread' : module.spread, 'ammotype' : module.ammo_type, 'ammocons' : module.ammo_consumption, 'firerate' : 1.0 / module.shoot_timer.wait_time } text += "Ammo type: {ammotype}\nAmmo consumption: {ammocons} units/usage\nFirerate: {firerate} usages/second\nSpread: {spread} degrees".format(format) label_mod_info.text = text