ui/BuyPhaseItem.razor
@using Sandbox;
@using Sandbox.UI;
@inherits Panel
@attribute [StyleSheet("BuyPhaseItem.razor.scss")]

@{
	var manager = Manager.Instance;
	var costsHP = Relic.DoesRelicCostHP(RelicType) || manager.Stats[StatType.AllItemsCostHP] > 0f;
	var playerLevel = (manager.GetRelic(RelicType)?.Level ?? 0);
	var shopLevel = playerLevel + 1 + (IsSold ? -1 : 0);
	var price = manager.Stats[StatType.FreeItem] > 0f ? 0 : Relic.GetRelicPrice(RelicType, shopLevel);
	var playerWealth = costsHP ? manager.HP - 1 : manager.Money;
	var canAfford = playerWealth >= price;
}

<root style="opacity:@((IsSold ? 0.4f : (!canAfford ? 0.66f : 1f))); background-color:@(costsHP ? "#550000aa" : "#000000aa"); border: 4px solid @(canAfford ? "#000000ff" : "#00000033");" onmouseover=@(() => OnMouseOver() ) onclick=@(() => BuyButtonClicked() )>
	<div class="name" style="opacity:@(IsSold ? 0.2f : 1f); color:@(canAfford ? "#fff" : "#ff777788");">@Relic.GetName(RelicType)</div>

	@if(shopLevel > 1)
	{
		<div class="level">@($"LVL {shopLevel}")</div>
	}

	<div class="icon" style="background-image:url(@Relic.GetIconFilename(RelicType));"></div>
	<div class="description" style="opacity:@(IsSold ? 0.2f : 1f);">
		@(shopLevel > 1 ? Relic.GetRelicUpgradeDescription(RelicType, shopLevel - 1, shopLevel) : Relic.GetRelicDescription(RelicType, shopLevel))
	</div>

	@if(!IsSold)
	{
		@*<div class="buy_button" style="opacity:@(canAfford ? 1f : 0.15f);" onmouseover=@(() => OnMouseOver() ) onclick=@(() => BuyButtonClicked() )>
			<div class="button_text">
				Buy
			</div>
		</div>*@
	}
	else
	{
		<div class="sold">@($"SOLD\n OUT")</div>
	}

	<div class="price_container" style="opacity:@(IsSold ? 0.5f : 1f);">
		@if(costsHP) 
		{
			<div class="hp_symbol">@("❤️")</div>
		}

		<div class="price" style="color:@(!IsSold ? (canAfford ? "#ffff77" : "#ff3333") : "#ffffff77");">@($"{(costsHP ? "" : "$")}{price}")</div>
	</div>
</root>

@code
{
	public RelicType RelicType { get; set; }
	public bool IsSold { get; set; }
	public int ItemIndex { get; set; }

	public void BuyButtonClicked()
	{
		var playerLevel = (Manager.Instance.GetRelic(RelicType)?.Level ?? 0);
		var shopLevel = playerLevel + 1;
		var price = Manager.Instance.Stats[StatType.FreeItem] > 0f ? 0 : Relic.GetRelicPrice(RelicType, shopLevel);
		var costsHP = Relic.DoesRelicCostHP(RelicType) || Manager.Instance.Stats[StatType.AllItemsCostHP] > 0f;
		var playerWealth = costsHP ? Manager.Instance.HP - 1 : Manager.Instance.Money;

		if(IsSold || price > playerWealth)
		{
			Manager.Instance.PlaySfxCenter("error_1", volume: 0.6f, pitch: Game.Random.Float(0.97f, 1.03f));
			return;
		}

		Manager.Instance.BoughtItems[ItemIndex] = true;

		// pirate flag
		if(price > 0 && Game.Random.Float(0f, 1f) < Manager.Instance.Stats[StatType.StealItemChance] && Manager.Instance.Stats[StatType.FreeItem] <= 0f)
		{
			Manager.Instance.PlaySfxCenter("pirate_flag", volume: 0.4f, pitch: Game.Random.Float(0.9f, 1.1f));

			SpawnFreeFloater();
		}
		else 
		{
			if(costsHP)
			{
				Manager.Instance.HP = Math.Max(Manager.Instance.HP - price, 0);
				Manager.Instance.TimeSinceHPChanged = 0f;

				if(price > 0)
				{
					Manager.Instance.PlaySfxCenter("hurt", volume: 1.2f, pitch: Game.Random.Float(0.8f, 0.9f));
					Manager.Instance.ShakeCamera(strength: Utils.Map(Manager.Instance.HP, Manager.Instance.MaxHP, 0, 1.5f, 2.5f, EasingType.SineIn), time: Utils.Map(Manager.Instance.HP, Manager.Instance.MaxHP, 0, 0.45f, 0.6f, EasingType.SineIn));
					Manager.Instance.ShowOverlayColor(Color.Red.WithAlpha(Utils.Map(Manager.Instance.HP, Manager.Instance.MaxHP, 0, 0.4f, 0.7f, EasingType.SineIn)), time: Utils.Map(Manager.Instance.HP, Manager.Instance.MaxHP, 0, 0.175f, 0.25f, EasingType.SineIn));

					var camera = Scene.Camera;
					var ray = camera.ScreenPixelToRay(new Vector3(Screen.Width / 2, Screen.Height / 2, 0f));
					var tr = Scene.Trace.Ray(ray, 10000f).Run();

					Manager.Instance.SpawnLoseHPFloater(price, tr.EndPosition + new Vector3(0f, -20f, 0f));
				}
			}
			else
			{
				Manager.Instance.SpendMoney(price);
			}

			if (Manager.Instance.Stats[StatType.FreeItem] > 0f)
				SpawnFreeFloater();
		}

		Manager.Instance.IncreaseRelicLevel(RelicType);

		if (Manager.Instance.Stats[StatType.FreeItem] > 0f)
			Manager.Instance.Stats[StatType.FreeItem] = 0f;

		if(Game.Random.Float(0f, 1f) < Manager.Instance.Stats[StatType.BuyItemHealChance])
		{
			var camera = Scene.Camera;
			var ray = camera.ScreenPixelToRay(new Vector3(Screen.Width / 2, Screen.Height / 2, 0f));
			var tr = Scene.Trace.Ray(ray, 10000f).Run();

			int healAmount = 1;

			Manager.Instance.SpawnHealHPFloater(healAmount, tr.EndPosition + new Vector3(0f, 45f, 0f));

			Manager.Instance.HP = Math.Min(Manager.Instance.HP + healAmount, Manager.Instance.MaxHP);
			Manager.Instance.TimeSinceHPChanged = 0f;

			Manager.Instance.PlaySfxCenter("juicebox", volume: 0.85f, pitch: Game.Random.Float(1.05f, 1.15f));
		}

		Manager.Instance.PlaySfx("click_0");
	}

	void OnMouseOver()
	{
		Manager.Instance.PlaySfx("click_1");
	}

	protected override int BuildHash()
	{
		var manager = Manager.Instance;
		return HashCode.Combine(
			RelicType,
			IsSold,
			manager.Money,
			manager.HP,
			manager.Stats[StatType.FreeItem],
			manager.Stats[StatType.AllItemsCostHP]
		// Time.Now
		);
	}

	void SpawnFreeFloater()
	{
		var mouse = Mouse.Position;
		var camera = Scene.Camera;
		var ray = camera.ScreenPixelToRay(mouse);

		var tr = Scene.Trace.Ray(ray, 10000f).Run();

		Manager.Instance.SpawnFloaterText(
			pos: tr.EndPosition,
			text: $"Free!",
			emojiText: "",
			lifetime: 0.5f,
			color: new Color(1f, 1f, 0.5f),
			velocity: new Vector2(0f, 80f),
			deceleration: 0.5f,
			fontSize: 45f
		);
	}
}