InventorySlot

user_4219213 avatar
user_4219213
plain_text
02/12/2026 5:12 AM
34.6 KB
9
Indexable
extends Node2D

# ─────────────────────────────────────
# Tweens / flags
# ─────────────────────────────────────
var tween_rot5: Tween
var tween_hover5: Tween
var tween_rot6: Tween
var tween_hover6: Tween
var tween_rot7: Tween
var tween_hover7: Tween
var tween_rot8: Tween
var tween_hover8: Tween

var is_on: bool = true
var active: bool = true
var vis: bool = false

var choice_frame: int = 0

# ─────────────────────────────────────
# ID ranges / constants
# ─────────────────────────────────────
const EMPTY_ID := 39
const SHIELD_MIN_ID := 51
const SHIELD_MAX_ID := 61

var burst_pos = 0
var overclock_pos = 1
var dmr_pos = 2
var laser_pos = 3
var vertical_grip_pos = 4
var angled_grip_pos = 5
var bmg_pos = 6
var shotgun_pos = 7
var piercing_pos = 8
var ricochet_pos = 9
var hollow_point_pos = 10
var armor_piercing_pos = 11
var explosive_rounds_pos = 12
var resonance_rounds_pos = 13
var concussive_rounds_pos = 14
var high_velocity_pos = 15
var mythic_rounds_pos = 16
var bounce_rounds_pos = 17
var brass_barrel_pos = 18
var suppressor_pos = 19
var stabalizing_barrel_pos = 20
var hellfire_barrel_pos = 21
var volatile_barrel_pos = 22
var deadeye_barrel_pos = 23
var nomad_lens_pos = 24
var cobalt_scope_pos = 25
var deadeye_optic_pos = 26
var siphon_pos = 27
var ammo_supply_pos = 28
var point_blank_pos = 29
var tactical_stock_pos = 30
var alloy_stock_pos = 31
var pouch_stock_pos = 32
var makeshift_stock_pos = 33
var extra_mag_pos = 34
var critical_mag_pos = 35
var quick_reload_pos = 36
var adaptive_mag_pos = 37
var explosive_mag_pos = 38

var ghost_grip_pos = 40
var titan_grip_pos = 41
var mini_rocket_pos = 42
var inferno_barrel_pos = 43
var grenade_launcher_pos = 44
var gambler_stock_pos = 45
var ramjet_suppressor_pos = 46
var kinetic_stab_pos = 47
var exponential_mag_pos = 48
var widow_rounds_pos = 49
var doomsday_trigger_pos = 50

var health_upgrade_pos = 51
var reload_brace_pos = 52
var shield_siphon_pos = 53
var polished_plates_pos = 54
var heal_step_pos = 55
var ricochet_mesh_pos = 56
var mechanic_iou_pos = 57
var shatterburst_pos = 58
var emp_charge_pos = 59
var second_chance_pos = 60

var shield_breaker_pos = 62
var pulse_rounds_pos = 63
var money_muzzle_pos = 64
var void_rounds_pos = 65
var oil_rounds_pos = 66
var aim_cpu_pos = 67
var deadeye_stock_pos = 68

var empty_pos = EMPTY_ID

var japan_translation_script = load("res://scripts/utilities/japanese_font_translation.gd")

# ─────────────────────────────────────
# Rarity star wiring
# ─────────────────────────────────────
@onready var rarity_star: Node = $starContainer
var _last_upgrade_id: int = -9999

# ─────────────────────────────────────
# Helpers: rarity / ids
# ─────────────────────────────────────
func _is_shield_id(id: int) -> bool:
	return id >= SHIELD_MIN_ID and id <= SHIELD_MAX_ID

func _rarity_to_stars(r: String) -> int:
	match r:
		"common": return 1
		"uncommon": return 2
		"rare": return 3
		"epic": return 4
		"legendary": return 5
		_: return 0

func _get_rarity_string_for_id(upgrade_id: int) -> String:
	# 1) Weapon rarity provider
	if typeof(Weapons) != TYPE_NIL and Weapons.has_method("get_rarity"):
		var r = Weapons.get_rarity(upgrade_id)
		if r != null and r != "" and r != "unknown":
			return String(r)

	# 2) Shield rarity provider
	if _is_shield_id(upgrade_id) and typeof(ShieldUpgrades) != TYPE_NIL and ShieldUpgrades.has_method("get_rarity"):
		var r2 = ShieldUpgrades.get_rarity(upgrade_id)
		if r2 != null and r2 != "" and r2 != "unknown":
			return String(r2)

	# 3) Upgrade menu helper
	if is_instance_valid(Global.upgrade_menu) and Global.upgrade_menu.has_method("rarity_of_upgrade"):
		var r3 = Global.upgrade_menu.rarity_of_upgrade(upgrade_id)
		if r3 != null and r3 != "" and r3 != "unknown":
			return String(r3)

	# 4) Fallback – treat unknowns as common so they still show at least 1 star
	return "common"

func _get_upgrade_id_for_this_slot() -> int:
	match self.name:
		"slot1":  return Global.inventory_1_pos
		"slot2":  return Global.inventory_2_pos
		"slot3":  return Global.inventory_3_pos
		"slot4":  return Global.inventory_4_pos
		"slot5":  return Global.inventory_5_pos
		"slot6":  return Global.inventory_6_pos
		"slot7":  return Global.inventory_7_pos
		"slot8":  return Global.inventory_8_pos
		"slot9":  return Global.inventory_9_pos
		"slot10": return Global.inventory_10_pos
		"slot11": return Global.inventory_11_pos
		"slot12": return Global.inventory_12_pos
		"slot13": return Global.inventory_13_pos
		"slot14": return Global.inventory_14_pos
		"slot15": return Global.inventory_15_pos
		"slot16": return Global.inventory_16_pos
		_:        return EMPTY_ID

func _set_this_inventory_pos(id: int) -> void:
	match self.name:
		"slot1":  Global.inventory_1_pos = id
		"slot2":  Global.inventory_2_pos = id
		"slot3":  Global.inventory_3_pos = id
		"slot4":  Global.inventory_4_pos = id
		"slot5":  Global.inventory_5_pos = id
		"slot6":  Global.inventory_6_pos = id
		"slot7":  Global.inventory_7_pos = id
		"slot8":  Global.inventory_8_pos = id
		"slot9":  Global.inventory_9_pos = id
		"slot10": Global.inventory_10_pos = id
		"slot11": Global.inventory_11_pos = id
		"slot12": Global.inventory_12_pos = id
		"slot13": Global.inventory_13_pos = id
		"slot14": Global.inventory_14_pos = id
		"slot15": Global.inventory_15_pos = id
		"slot16": Global.inventory_16_pos = id

func _set_star_value(stars: int, do_blurb: bool) -> void:
	if !is_instance_valid(rarity_star):
		return
	rarity_star.visible = stars > 0
	if stars <= 0:
		return

	if rarity_star.has_method("set_rarity"):
		rarity_star.set_rarity(stars)
	elif "rarity" in rarity_star:
		rarity_star.rarity = stars
	elif "stars" in rarity_star:
		rarity_star.stars = stars

	if rarity_star.has_method("refresh"):
		rarity_star.refresh()

	if do_blurb and rarity_star.has_method("blurb"):
		rarity_star.blurb()
		if self.is_in_group("slotsToBlurb"):
			blurb2()

func _update_star_for_current_slot(do_blurb: bool = false) -> void:
	var upgrade_id := _get_upgrade_id_for_this_slot()

	# Empty / invalid → hide (note: 0 is valid Burst, so only < 0 is invalid)
	if upgrade_id == EMPTY_ID or upgrade_id < 0:
		if is_instance_valid(rarity_star):
			rarity_star.visible = false
		_last_upgrade_id = upgrade_id
		return

	var rarity_str := _get_rarity_string_for_id(upgrade_id)
	if rarity_str == "" or rarity_str == "unknown":
		rarity_str = "common"

	var stars := _rarity_to_stars(rarity_str)
	_set_star_value(stars, do_blurb)
	_last_upgrade_id = upgrade_id

# ─────────────────────────────────────
# Shield routing helpers
# ─────────────────────────────────────
func _place_in_first_empty_shield_slot(id: int) -> bool:
	var slots := get_tree().get_nodes_in_group("ShieldUpgradeSlots")
	for s in slots:
		if !is_instance_valid(s):
			continue
		var choice := _get_choice_sprite_from_slot_node(s)
		if choice == null:
			continue
		if choice.frame == EMPTY_ID:
			choice.frame = id
			if s.has_method("_update_star_for_current_choice"):
				s._update_star_for_current_choice(true)
			elif s.has_method("_update_star_for_current_slot"):
				s._update_star_for_current_slot(true)
			_apply_shield_flag_on_equip(id)
			return true
	return false

func _apply_shield_flag_on_equip(id: int) -> void:
	if typeof(ShieldUpgrades) == TYPE_NIL:
		return

	match id:
		health_upgrade_pos:
			ShieldUpgrades.health_upgrade = true
		reload_brace_pos:
			ShieldUpgrades.reload_brace = true
		shield_siphon_pos:
			ShieldUpgrades.siphon = true
		polished_plates_pos:
			ShieldUpgrades.polished_plates = true
		heal_step_pos:
			ShieldUpgrades.heal_step = true
		ricochet_mesh_pos:
			ShieldUpgrades.ricochet_mesh = true
		mechanic_iou_pos:
			ShieldUpgrades.mechanic_iou = true
		shatterburst_pos:
			ShieldUpgrades.shatterburst = true
		emp_charge_pos:
			ShieldUpgrades.emp_charge = true
		second_chance_pos:
			ShieldUpgrades.second_chance = true

func _get_choice_sprite_from_slot_node(slot_node: Node) -> Sprite2D:
	if slot_node == null:
		return null

	var paths := [
		"container/choice",
		"slotContainer/slotContainer2/choice",
		"choice"
	]
	for p in paths:
		var n := slot_node.get_node_or_null(p)
		if n and n is Sprite2D:
			return n

	return slot_node.find_child("choice", true, false) as Sprite2D

# ─────────────────────────────────────
# Inventory root helper (for sfx)
# ─────────────────────────────────────
func _get_inventory_root() -> Node:
	var n: Node = self
	while n:
		if n.has_method("play_purchase_sfx"):
			return n
		n = n.get_parent()
	return null

# ─────────────────────────────────────
# Lifecycle
# ─────────────────────────────────────
func _ready() -> void:
	$no.bus = "sfx"
	add_to_group("inventory_upgrade_slots") # optional; not required, but useful for debugging
	add_to_group("slotsToBlurb")

	$slotContainer/slotContainer2/choice.rotation_degrees = randf_range(-4.0, 4.0)
	$slotContainer/slotContainer2/choice.hframes = Global.amount_of_upgrades

	$add1/container/container2/Sprite2D/textContainer/deleteText.set_script(japan_translation_script)
	$delete1/container/container2/Sprite2D/textContainer/deleteText.set_script(japan_translation_script)

	_update_star_for_current_slot(false)

func _process(_delta: float) -> void:
	choice_frame = $slotContainer/slotContainer2/choice.frame

	$delete1/container/container2/Sprite2D/textContainer.scale = Vector2(0.6, 0.6)

	if !Global.tutorial_active:
		if $slotContainer/slotContainer2/choice/Sprite2D:
			$slotContainer/slotContainer2/choice/Sprite2D.visible = false
			$slotContainer/slotContainer2/choice/Sprite2D.scale = Vector2(0, 0)

	# Language layout tweaks
	if Global.language_num == 4 or Global.language_num == 5 or Global.language_num == 10:
		$add1/container/container2/Sprite2D/textContainer.position = Vector2(-0.082, -1.103)
		$add1/container/container2/Sprite2D/textContainer.scale = Vector2(0.8, 0.8)
		$delete1/container/container2/Sprite2D/textContainer.position = Vector2(0.075, -0.425)
		$delete1/container/container2/Sprite2D/textContainer.scale = Vector2(0.8, 0.8)

	# Keep star synced if Global.inventory_* changed externally
	var current_id := _get_upgrade_id_for_this_slot()
	if current_id != _last_upgrade_id:
		_update_star_for_current_slot(false)

	# Register this slot into Global when the panel is visible
	var root_panel := _get_inventory_root()
	if root_panel and root_panel.visible:
		match self.name:
			"slot1":  Global.Slot1 = self
			"slot2":  Global.Slot2 = self
			"slot3":  Global.Slot3 = self
			"slot4":  Global.Slot4 = self
			"slot5":  Global.Slot5 = self
			"slot6":  Global.Slot6 = self
			"slot7":  Global.Slot7 = self
			"slot8":  Global.Slot8 = self
			"slot9":  Global.Slot9 = self
			"slot10": Global.Slot10 = self
			"slot11": Global.Slot11 = self
			"slot12": Global.Slot12 = self
			"slot13": Global.Slot13 = self
			"slot14": Global.Slot14 = self
			"slot15": Global.Slot15 = self
			"slot16": Global.Slot16 = self

	$add1/container/container2/Sprite2D/textContainer/deleteText.text = "[wave amp=30.0 freq=10.0 connected=1][center]" + tr("ADD") + "[color=#e9a926][/color][/center]"

	var base_price := _get_base_price_for_id(choice_frame)
	var sell_value := int(base_price / 2)

	if sell_value > 0:
		$delete1/container/container2/Sprite2D/textContainer/deleteText.text = "[wave amp=30.0 freq=10.0 connected=1][center]" + tr("SELL") + "[color=#e9a926] - $" + str(sell_value) + "[/color][/center]"
	else:
		$delete1/container/container2/Sprite2D/textContainer/deleteText.text = "[wave amp=30.0 freq=10.0 connected=1][center]" + tr("SELL") + "[color=#e9a926][/color][/center]"

func _weapon_already_has_upgrade(id: int) -> bool:
	# Only applies to weapon upgrades; shield upgrades are separate slots (51–61)
	if id == EMPTY_ID:
		return false
	if _is_shield_id(id):
		return false

	# Primary check: live weapon upgrade slot nodes
	for n in get_tree().get_nodes_in_group("weapon_upgrade_slots"):
		if !is_instance_valid(n):
			continue
		var choice := n.get_node_or_null("container/choice")
		if choice and choice is Sprite2D:
			if int(choice.frame) == id:
				return true

	# Fallback check: saved slot ids in Weapons.dict_on
	for k in ["Slot1","Slot2","Slot3","Slot4","Slot5","Slot6","Slot7","Slot8"]:
		if Weapons.dict_on.has(k) and int(Weapons.dict_on[k]) == id:
			return true

	return false


func _flash_duplicate_denied() -> void:
	# Optional UX: flash a "no slot" style animation if you have it
	if has_node("NoSlotFlash") and $NoSlotFlash.has_node("AnimationPlayer"):
		$NoSlotFlash/AnimationPlayer.play("flash")
	# You can add a specific sound here if you want

func _get_base_price_for_id(id: int) -> int:
	var price := 0

	match id:
		# Weapon upgrades
		burst_pos:                price = Upgrades.burst_price
		overclock_pos:            price = Upgrades.overclock_price
		dmr_pos:                  price = Upgrades.dmr_price
		laser_pos:                price = Upgrades.laser_price
		vertical_grip_pos:        price = Upgrades.vertical_grip_price
		angled_grip_pos:          price = Upgrades.angled_grip_price
		bmg_pos:                  price = Upgrades.bmg_price
		shotgun_pos:              price = Upgrades.shotgun_price
		piercing_pos:             price = Upgrades.piercing_price
		ricochet_pos:             price = Upgrades.ricochet_price
		hollow_point_pos:         price = Upgrades.hollow_point_price
		armor_piercing_pos:       price = Upgrades.armor_piercing_price
		explosive_rounds_pos:     price = Upgrades.explosive_rounds_price
		resonance_rounds_pos:     price = Upgrades.resonance_rounds_price
		concussive_rounds_pos:    price = Upgrades.concussive_rounds_price
		high_velocity_pos:        price = Upgrades.high_velocity_price
		mythic_rounds_pos:        price = Upgrades.mythic_rounds_price
		bounce_rounds_pos:        price = Upgrades.bounce_rounds_price
		brass_barrel_pos:         price = Upgrades.brass_barrel_price
		suppressor_pos:           price = Upgrades.suppressor_price
		stabalizing_barrel_pos:   price = Upgrades.stabalizing_barrel_price
		hellfire_barrel_pos:      price = Upgrades.hellfire_barrel_price
		volatile_barrel_pos:      price = Upgrades.volatile_barrel_price
		deadeye_barrel_pos:       price = Upgrades.deadeye_barrel_price
		nomad_lens_pos:           price = Upgrades.nomad_lens_price
		cobalt_scope_pos:         price = Upgrades.cobalt_scope_price
		deadeye_optic_pos:        price = Upgrades.deadeye_optic_price
		siphon_pos:               price = Upgrades.siphon_price
		ammo_supply_pos:          price = Upgrades.ammo_supply_price
		point_blank_pos:          price = Upgrades.point_blank_price
		tactical_stock_pos:       price = Upgrades.tactical_stock_price
		alloy_stock_pos:          price = Upgrades.alloy_stock_price
		pouch_stock_pos:          price = Upgrades.pouch_stock_price
		makeshift_stock_pos:      price = Upgrades.makeshift_stock_price
		extra_mag_pos:            price = Upgrades.extra_mag_price
		critical_mag_pos:         price = Upgrades.critical_mag_price
		quick_reload_pos:         price = Upgrades.quick_reload_price
		adaptive_mag_pos:         price = Upgrades.adaptive_mag_price
		explosive_mag_pos:        price = Upgrades.explosive_mag_price

		# Legendary upgrades
		ghost_grip_pos:           price = Upgrades.ghost_grip_price
		titan_grip_pos:           price = Upgrades.titan_grip_price
		mini_rocket_pos:          price = Upgrades.mini_rocket_price
		inferno_barrel_pos:       price = Upgrades.inferno_barrel_price
		grenade_launcher_pos:     price = Upgrades.grenade_launcher_price
		gambler_stock_pos:        price = Upgrades.gamblers_stock_price
		ramjet_suppressor_pos:    price = Upgrades.ramjet_suppressor_price
		kinetic_stab_pos:         price = Upgrades.kinetic_stabilizer_price
		exponential_mag_pos:      price = Upgrades.exponential_magazine_price
		widow_rounds_pos:         price = Upgrades.widow_rounds_price
		doomsday_trigger_pos:     price = Upgrades.doomsday_trigger_price

		# Shield upgrades
		health_upgrade_pos:       price = ShieldUpgrades.health_upgrade_price
		reload_brace_pos:         price = ShieldUpgrades.reload_brace_price
		shield_siphon_pos:        price = ShieldUpgrades.siphon_price
		polished_plates_pos:      price = ShieldUpgrades.polished_plates_price
		heal_step_pos:            price = ShieldUpgrades.heal_step_price
		ricochet_mesh_pos:        price = ShieldUpgrades.ricochet_mesh_price
		mechanic_iou_pos:         price = ShieldUpgrades.mechanic_iou_price
		shatterburst_pos:         price = ShieldUpgrades.shatterburst_price
		emp_charge_pos:           price = ShieldUpgrades.emp_charge_price
		second_chance_pos:        price = ShieldUpgrades.second_chance_price

		shield_breaker_pos:        price = Upgrades.shield_breaker_rounds_price
		pulse_rounds_pos:        price = Upgrades.pulse_rounds_price
		money_muzzle_pos:        price = Upgrades.money_muzzle_price
		void_rounds_pos:        price = Upgrades.void_rounds_price
		oil_rounds_pos:        price = Upgrades.oil_rounds_price
		aim_cpu_pos:        price = Upgrades.aim_cpu_price
		deadeye_stock_pos:        price = Upgrades.deadeye_stock_price

		empty_pos:
			price = 0
		_:
			price = 0

	return price

# ─────────────────────────────────────
# Open / close widget
# ─────────────────────────────────────
func _on_choice_1_button_pressed() -> void:
	if $slotContainer/slotContainer2/choice.frame == EMPTY_ID:
		return

	is_on = !is_on
	if Global.slot_on:
		is_on = true

	if !is_on and !Global.slot_on:
		$slotContainer/slotContainer2/choice/mainFlash.visible = true
		$container.scale = Vector2.ONE
		Global.slot_on = true
		$delete1.enter()
		$add1.enter()
		blurb2()
		vis = true
		$delete1/ColorRect/AnimationPlayer.play("flash")
		$add1/ColorRect/AnimationPlayer.play("flash")
		_update_star_for_current_slot(true)
	elif is_on and vis:
		$slotContainer/slotContainer2/choice/mainFlash.visible = false
		$container.scale = Vector2.ZERO
		Global.slot_on = false
		exit()
		$delete1.exit()
		$add1.exit()
		blurb2()
		vis = false
		$delete1/ColorRect/AnimationPlayer.play("flash")
		$add1/ColorRect/AnimationPlayer.play("flash")

func _on_choice_1_button_mouse_entered() -> void:
	print("HIGHLIGH")
	Global.hover_choice_inventory_num = $slotContainer/slotContainer2/choice.frame
	if Global.slot_on:
		return
	enter()

func _on_choice_1_button_mouse_exited() -> void:
	if Global.slot_on:
		return
	exit()

func enter() -> void:
	active = true
	tween_hover7 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
	tween_hover7.tween_property(self, "scale", Vector2(1.2, 1.2), 0.5)
	if $hover/Timer.is_stopped():
		$hover.play()
		$hover/Timer.start()

func exit() -> void:
	active = false
	tween_rot7 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK).set_parallel(true)
	tween_hover7 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
	tween_hover7.tween_property(self, "scale", Vector2.ONE, 0.55)

func exit2() -> void:
	if tween_rot7 and tween_rot7.is_running():
		tween_rot7.kill()
	tween_rot7 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK).set_parallel(true)
	if tween_hover7 and tween_hover7.is_running():
		tween_hover7.kill()
	tween_hover7 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
	tween_hover7.tween_property(self, "scale", Vector2.ONE, 0.55)

func blurb() -> void:
	if tween_hover6 and tween_hover6.is_running():
		tween_hover6.kill()
	tween_hover6 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
	tween_hover6.tween_property($slotContainer/slotContainer2, "scale", Vector2(1.1, 1.1), 0.5)
	await get_tree().create_timer(0.05).timeout
	if tween_rot6 and tween_rot6.is_running():
		tween_rot6.kill()
	tween_rot6 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK).set_parallel(true)
	if tween_hover6 and tween_hover6.is_running():
		tween_hover6.kill()
	tween_hover6 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
	tween_hover6.tween_property($slotContainer/slotContainer2, "scale", Vector2(1.0, 1.0), 0.55)

func blurb2() -> void:
	if tween_hover8 and tween_hover8.is_running():
		tween_hover8.kill()
	tween_hover8 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
	tween_hover8.tween_property($slotContainer/slotContainer2, "scale", Vector2(1.25, 1.25), 0.5)
	await get_tree().create_timer(0.05).timeout
	if tween_rot8 and tween_rot8.is_running():
		tween_rot8.kill()
	tween_rot8 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK).set_parallel(true)
	if tween_hover8 and tween_hover8.is_running():
		tween_hover8.kill()
	tween_hover8 = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
	tween_hover8.tween_property($slotContainer/slotContainer2, "scale", Vector2(1.0, 1.0), 0.55)

func no():
	$no.play()
	$slotContainer/slotContainer2/choice/malusFlash.visible = true
	await get_tree().create_timer(0.15).timeout
	$slotContainer/slotContainer2/choice/malusFlash.visible = false

# ─────────────────────────────────────
# Delete from inventory
# ─────────────────────────────────────
func _on_delete_button_pressed() -> void:
	price_sell_stuff()
	$delete1.close()
	$add1.close()
	delete_stuff()
	close_stuff()

func delete_stuff() -> void:
	$add1/click.play()
	$slotContainer/slotContainer2/choice/mainFlash.visible = false
	_set_this_inventory_pos(EMPTY_ID)
	_update_star_for_current_slot(false)

# ─────────────────────────────────────
# Add / swap
# ─────────────────────────────────────
func swap_func() -> void:
	var placed := add_stuff()
	if placed:
		delete_stuff()
	close_stuff()

func _on_add_button_pressed() -> void:
	close_stuff()
	$add1.close()
	$click2.play()
	$delete1.close()

	var id = $slotContainer/slotContainer2/choice.frame

	# Shield items: bypass weapon-slot gating
	if _is_shield_id(id):
		var placed := add_stuff()
		if placed:
			delete_stuff()
		return

	# NEW: Block equipping duplicate weapon upgrades
	if _weapon_already_has_upgrade(id):
		_flash_duplicate_denied()
		print("Duplicate upgrade blocked (already equipped on weapon): ", id)
		return

	var placed := add_stuff()
	if placed:
		delete_stuff()
	else:
		_flash_duplicate_denied() # reuse your deny flash, or make a different one
		no()
	return


func stuff() -> void:
	var placed := add_stuff()
	if placed:
		delete_stuff()

func add_stuff() -> bool:
	if Global.tutorial_active:
		Global.dont_let_upgrade_bench = false
		Global.stop_disable_upgrade_bench = true

	$slotContainer/slotContainer2/choice/mainFlash.visible = false

	if $slotContainer/slotContainer2/choice.has_node("Sprite2D"):
		var spr: Node = $slotContainer/slotContainer2/choice/Sprite2D
		spr.visible = false
		if spr.has_node("AnimationPlayer"):
			spr.get_node("AnimationPlayer").stop()

	var new_id = $slotContainer/slotContainer2/choice.frame

	if _is_shield_id(new_id):
		var placed := _place_in_first_empty_shield_slot(new_id)
		if !placed:
			if has_node("NoSlotFlash"):
				$NoSlotFlash/AnimationPlayer.play("flash")
			print("No empty shield slot found; leaving shield upgrade in inventory.")
			return false
		_update_star_for_current_slot(true)
		return true
	else:
		if is_instance_valid(Global.weapon_inventory) and Global.weapon_inventory.has_method("change_upgrades"):
			var ok: bool = Global.weapon_inventory.change_upgrades(new_id)
			if ok:
				_update_star_for_current_slot(true)
				return true
			# No compatible empty slot of the right type
			if has_node("NoSlotFlash"):
				$NoSlotFlash/AnimationPlayer.play("flash")
			print("No compatible empty weapon slot for upgrade id: ", new_id)
			return false

		print("weapon_inventory.change_upgrades not available; not removing from inventory.")
		return false


# ─────────────────────────────────────
# Misc signal handlers
# ─────────────────────────────────────
func _on_choice_1_button_2_mouse_exited() -> void:
	pass

func _on_choice_1_button_2_mouse_entered() -> void:
	close_stuff()

func _on_choice_1_button_3_mouse_entered() -> void:
	close_stuff()

func _on_choice_1_button_4_mouse_entered() -> void:
	close_stuff()

func _on_choice_1_button_5_mouse_entered() -> void:
	close_stuff()

func close_stuff() -> void:
	if Global.slot_on:
		$slotContainer/slotContainer2/choice/mainFlash.visible = false
		$container.scale = Vector2.ZERO
		is_on = true
		Global.slot_on = false
		exit()
		$delete1.exit()
		$add1.exit()
		$delete1/ColorRect/AnimationPlayer.play("flash")
		$add1/ColorRect/AnimationPlayer.play("flash")
		vis = false

# ─────────────────────────────────────
# Sell pricing
# ─────────────────────────────────────

func price_sell_stuff() -> void:
	var root := _get_inventory_root()
	if root:
		root.play_purchase_sfx()

	var id = $slotContainer/slotContainer2/choice.frame
	var base_price := _get_base_price_for_id(id)

	if base_price > 0:
		# You only get half back when selling
		Global.money += base_price / 2
Editor is loading...
Leave a Comment