623 lines
24 KiB
C#
623 lines
24 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class UpgradeManager : MonoBehaviour
|
|
{
|
|
enum FreeUpgradeType
|
|
{
|
|
KillBonus,
|
|
HitBonus
|
|
}
|
|
|
|
struct CardDefinition
|
|
{
|
|
public UpgradeCard.UpgradeType type;
|
|
public string title;
|
|
public string description;
|
|
public string rarity;
|
|
public int maxStacks;
|
|
public int baseCost;
|
|
}
|
|
|
|
struct UpgradeOffer
|
|
{
|
|
public UpgradeCard.UpgradeType paidType;
|
|
public FreeUpgradeType freeType;
|
|
public bool isFree;
|
|
public string title;
|
|
public string description;
|
|
public string footer;
|
|
public string rarity;
|
|
}
|
|
|
|
public Tower tower;
|
|
public int bits = 5;
|
|
public TextMeshProUGUI bitsText;
|
|
|
|
readonly Dictionary<UpgradeCard.UpgradeType, int> upgradeLevels = new Dictionary<UpgradeCard.UpgradeType, int>();
|
|
readonly Dictionary<UpgradeCard.UpgradeType, int> upgradeCosts = new Dictionary<UpgradeCard.UpgradeType, int>();
|
|
|
|
GameObject choiceOverlay;
|
|
Action currentChoiceComplete;
|
|
int bonusBitsPerKill;
|
|
float hitBitChance;
|
|
|
|
static readonly CardDefinition[] CannonCards =
|
|
{
|
|
Card(UpgradeCard.UpgradeType.ReinforcedPowder, "REINFORCED POWDER", "Shell Damage +15%.", "Common", 8, 3),
|
|
Card(UpgradeCard.UpgradeType.ExpandedPayload, "EXPANDED PAYLOAD", "Blast Radius +12%.", "Common", 6, 3),
|
|
Card(UpgradeCard.UpgradeType.AutoLoader, "AUTO-LOADER", "Reload Speed +10%.", "Common", 8, 3),
|
|
Card(UpgradeCard.UpgradeType.HeavyCaliber, "HEAVY CALIBER", "Shells gain +25% damage but Reload Speed -8%.", "Uncommon", 5, 5),
|
|
Card(UpgradeCard.UpgradeType.ShockwaveShells, "SHOCKWAVE SHELLS", "Explosion knockback increased slightly.", "Uncommon", 4, 5),
|
|
Card(UpgradeCard.UpgradeType.ShrapnelRounds, "SHRAPNEL ROUNDS", "Explosion edges deal shrapnel damage equal to 35% shell damage.", "Rare", 5, 7),
|
|
Card(UpgradeCard.UpgradeType.FragmentBurst, "FRAGMENT BURST", "Explosions release 3 metal fragments.", "Rare", 3, 7),
|
|
Card(UpgradeCard.UpgradeType.BurningDebris, "BURNING DEBRIS", "Explosions leave burning ground for 2 seconds.", "Rare", 4, 7),
|
|
Card(UpgradeCard.UpgradeType.ConcussiveImpact, "CONCUSSIVE IMPACT", "Explosion hits slow enemies by 20% for 1 second.", "Rare", 3, 7),
|
|
Card(UpgradeCard.UpgradeType.CraterMaker, "CRATER MAKER", "Direct hits create a lingering slowing crater.", "Epic", 2, 10),
|
|
Card(UpgradeCard.UpgradeType.ChainDetonation, "CHAIN DETONATION", "Enemies killed by explosions detonate for 20% shell damage.", "Epic", 3, 10),
|
|
Card(UpgradeCard.UpgradeType.SiegeShells, "SIEGE SHELLS", "Every 5th shot fires a massive shell. Stacks reduce required shots.", "Epic", 3, 10),
|
|
Card(UpgradeCard.UpgradeType.ArmorPiercingCore, "ARMOR-PIERCING CORE", "Direct-hit damage pierces defenses, increasing direct damage.", "Rare", 4, 7),
|
|
Card(UpgradeCard.UpgradeType.DoubleCharge, "DOUBLE CHARGE", "Every reload has a 20% chance to instantly load a second shell.", "Rare", 3, 7),
|
|
Card(UpgradeCard.UpgradeType.SiegePlatform, "SIEGE PLATFORM", "Stable firing increases damage by 35%.", "Epic", 2, 10),
|
|
Card(UpgradeCard.UpgradeType.ExecutionShell, "EXECUTION SHELL", "Shells deal bonus damage to enemies above 80% health.", "Uncommon", 4, 5),
|
|
Card(UpgradeCard.UpgradeType.FinisherPayload, "FINISHER PAYLOAD", "Shells deal bonus damage to enemies below 30% health.", "Uncommon", 4, 5),
|
|
Card(UpgradeCard.UpgradeType.StabilizedBarrel, "STABILIZED BARREL", "Projectile speed +30%.", "Common", 4, 3),
|
|
Card(UpgradeCard.UpgradeType.SmartTargeting, "SMART TARGETING", "Prioritizes enemies near the center tower.", "Rare", 1, 7),
|
|
Card(UpgradeCard.UpgradeType.RangefinderOptics, "RANGEFINDER OPTICS", "Tower range +18%.", "Common", 5, 3),
|
|
Card(UpgradeCard.UpgradeType.DelayedFuse, "DELAYED FUSE", "Shells explode slightly later for deeper penetration and radius.", "Rare", 2, 7),
|
|
Card(UpgradeCard.UpgradeType.OverloadedChamber, "OVERLOADED CHAMBER", "Damage +40%, Reload Speed -15%.", "Rare", 3, 7),
|
|
Card(UpgradeCard.UpgradeType.VolatileMunitions, "VOLATILE MUNITIONS", "Critical kills create secondary explosions.", "Epic", 2, 10),
|
|
Card(UpgradeCard.UpgradeType.GlassCannonDesign, "GLASS CANNON DESIGN", "Massive damage, but pauses after every 10 shots to cool down.", "Legendary", 1, 14),
|
|
Card(UpgradeCard.UpgradeType.ApocalypseRound, "APOCALYPSE ROUND", "Every 20th shot fires an enormous extreme-damage shell.", "Legendary", 1, 14),
|
|
};
|
|
|
|
void Start()
|
|
{
|
|
InitializeUpgrades();
|
|
EnsureBitsText();
|
|
UpdateBitsText();
|
|
}
|
|
|
|
public void EnemyKilled()
|
|
{
|
|
bits += 1 + bonusBitsPerKill;
|
|
UpdateBitsText();
|
|
}
|
|
|
|
public void EnemyHitByBullet()
|
|
{
|
|
if (hitBitChance <= 0f)
|
|
return;
|
|
|
|
if (UnityEngine.Random.value <= hitBitChance)
|
|
{
|
|
bits++;
|
|
UpdateBitsText();
|
|
}
|
|
}
|
|
|
|
public void ShowWaveUpgradeChoice(Action onChoiceComplete)
|
|
{
|
|
if (choiceOverlay != null)
|
|
return;
|
|
|
|
InitializeUpgrades();
|
|
EnsureBitsText();
|
|
currentChoiceComplete = onChoiceComplete;
|
|
|
|
List<UpgradeOffer> offers = BuildOffers();
|
|
if (offers.Count == 0)
|
|
{
|
|
CompleteChoice();
|
|
return;
|
|
}
|
|
|
|
Time.timeScale = 0f;
|
|
choiceOverlay = CreateOverlay(offers[0].isFree);
|
|
RectTransform row = CreateRect("UpgradeChoices", choiceOverlay.transform);
|
|
row.anchorMin = new Vector2(0.5f, 0.5f);
|
|
row.anchorMax = new Vector2(0.5f, 0.5f);
|
|
row.pivot = new Vector2(0.5f, 0.5f);
|
|
row.anchoredPosition = new Vector2(0f, -12f);
|
|
row.sizeDelta = new Vector2(700f, 212f);
|
|
|
|
HorizontalLayoutGroup layout = row.gameObject.AddComponent<HorizontalLayoutGroup>();
|
|
layout.spacing = 16f;
|
|
layout.childAlignment = TextAnchor.MiddleCenter;
|
|
layout.childControlWidth = true;
|
|
layout.childControlHeight = true;
|
|
layout.childForceExpandWidth = false;
|
|
layout.childForceExpandHeight = false;
|
|
|
|
foreach (UpgradeOffer offer in offers)
|
|
CreateChoiceCard(offer, row);
|
|
}
|
|
|
|
public void ShowSpecialUpgradeChoice()
|
|
{
|
|
ShowWaveUpgradeChoice(null);
|
|
}
|
|
|
|
public void TryUpgrade(UpgradeCard.UpgradeType type)
|
|
{
|
|
if (!upgradeCosts.ContainsKey(type) || bits < upgradeCosts[type] || IsAtMaxStacks(type))
|
|
return;
|
|
|
|
BuyPaidUpgrade(type);
|
|
}
|
|
|
|
void InitializeUpgrades()
|
|
{
|
|
foreach (CardDefinition card in CannonCards)
|
|
{
|
|
if (!upgradeLevels.ContainsKey(card.type))
|
|
upgradeLevels[card.type] = 0;
|
|
if (!upgradeCosts.ContainsKey(card.type))
|
|
upgradeCosts[card.type] = card.baseCost;
|
|
}
|
|
}
|
|
|
|
List<UpgradeOffer> BuildOffers()
|
|
{
|
|
List<UpgradeOffer> paidOffers = new List<UpgradeOffer>();
|
|
foreach (CardDefinition card in CannonCards)
|
|
{
|
|
int cost = upgradeCosts[card.type];
|
|
if (bits < cost || IsAtMaxStacks(card.type))
|
|
continue;
|
|
|
|
int nextLevel = upgradeLevels[card.type] + 1;
|
|
paidOffers.Add(new UpgradeOffer
|
|
{
|
|
paidType = card.type,
|
|
isFree = false,
|
|
title = card.maxStacks == 1 ? card.title : $"{card.title} {ToRoman(nextLevel)}",
|
|
description = card.description,
|
|
footer = $"Cost: {cost} Bits",
|
|
rarity = card.rarity
|
|
});
|
|
}
|
|
|
|
if (paidOffers.Count > 0)
|
|
return PickRandomWeighted(paidOffers, 3);
|
|
|
|
return new List<UpgradeOffer>
|
|
{
|
|
new UpgradeOffer
|
|
{
|
|
freeType = FreeUpgradeType.KillBonus,
|
|
isFree = true,
|
|
title = $"SALVAGE BONUS {ToRoman(bonusBitsPerKill + 1)}",
|
|
description = "Enemies killed give +1 extra bit from now on.",
|
|
footer = "Free",
|
|
rarity = "Supply"
|
|
},
|
|
new UpgradeOffer
|
|
{
|
|
freeType = FreeUpgradeType.HitBonus,
|
|
isFree = true,
|
|
title = $"SCRAP ROUNDS {ToRoman(Mathf.RoundToInt(hitBitChance / 0.4f) + 1)}",
|
|
description = "Bullet hits gain a +40% chance to give 1 bit.",
|
|
footer = "Free",
|
|
rarity = "Supply"
|
|
}
|
|
};
|
|
}
|
|
|
|
static List<UpgradeOffer> PickRandomWeighted(List<UpgradeOffer> source, int count)
|
|
{
|
|
List<UpgradeOffer> pool = new List<UpgradeOffer>(source);
|
|
List<UpgradeOffer> result = new List<UpgradeOffer>();
|
|
|
|
while (pool.Count > 0 && result.Count < count)
|
|
{
|
|
float totalWeight = 0f;
|
|
foreach (UpgradeOffer offer in pool)
|
|
totalWeight += GetRarityWeight(offer.rarity);
|
|
|
|
float roll = UnityEngine.Random.value * totalWeight;
|
|
int pickedIndex = 0;
|
|
for (int i = 0; i < pool.Count; i++)
|
|
{
|
|
roll -= GetRarityWeight(pool[i].rarity);
|
|
if (roll <= 0f)
|
|
{
|
|
pickedIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
result.Add(pool[pickedIndex]);
|
|
pool.RemoveAt(pickedIndex);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static float GetRarityWeight(string rarity)
|
|
{
|
|
switch (rarity)
|
|
{
|
|
case "Common": return 10f;
|
|
case "Uncommon": return 6f;
|
|
case "Rare": return 3.5f;
|
|
case "Epic": return 1.5f;
|
|
case "Legendary": return 0.55f;
|
|
default: return 1f;
|
|
}
|
|
}
|
|
|
|
void CreateChoiceCard(UpgradeOffer offer, Transform parent)
|
|
{
|
|
GameObject cardObject = new GameObject(offer.title + "Card", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button));
|
|
RectTransform cardRect = cardObject.GetComponent<RectTransform>();
|
|
cardRect.SetParent(parent, false);
|
|
|
|
LayoutElement layout = cardObject.AddComponent<LayoutElement>();
|
|
layout.preferredWidth = 212f;
|
|
layout.preferredHeight = 198f;
|
|
layout.minWidth = layout.preferredWidth;
|
|
layout.minHeight = layout.preferredHeight;
|
|
|
|
Image image = cardObject.GetComponent<Image>();
|
|
image.color = offer.isFree ? new Color(0.11f, 0.17f, 0.13f, 0.98f) : GetRarityColor(offer.rarity);
|
|
|
|
Button button = cardObject.GetComponent<Button>();
|
|
ColorBlock colors = button.colors;
|
|
colors.normalColor = image.color;
|
|
colors.highlightedColor = image.color + new Color(0.04f, 0.05f, 0.06f, 0f);
|
|
colors.pressedColor = new Color(0.06f, 0.28f, 0.36f, 1f);
|
|
colors.selectedColor = colors.highlightedColor;
|
|
colors.disabledColor = new Color(0.08f, 0.08f, 0.09f, 0.78f);
|
|
colors.colorMultiplier = 1f;
|
|
button.colors = colors;
|
|
button.onClick.AddListener(() => SelectOffer(offer));
|
|
|
|
TextMeshProUGUI rarity = CreateText("Rarity", cardRect, offer.rarity.ToUpperInvariant(), 11f, FontStyles.Bold, TextAlignmentOptions.Center);
|
|
TextMeshProUGUI title = CreateText("Title", cardRect, offer.title, 16f, FontStyles.Bold, TextAlignmentOptions.Center);
|
|
TextMeshProUGUI description = CreateText("Description", cardRect, offer.description, 12f, FontStyles.Normal, TextAlignmentOptions.TopLeft);
|
|
TextMeshProUGUI footer = CreateText("Footer", cardRect, offer.footer, 14f, FontStyles.Bold, TextAlignmentOptions.Center);
|
|
footer.color = offer.isFree ? new Color(0.56f, 0.95f, 0.58f, 1f) : new Color(0.98f, 0.87f, 0.32f, 1f);
|
|
|
|
PlaceCardText(rarity.rectTransform, 12f, -8f, -12f, 18f, true);
|
|
PlaceCardText(title.rectTransform, 12f, -30f, -12f, 46f, true);
|
|
PlaceCardText(description.rectTransform, 16f, -82f, -16f, 72f, true);
|
|
PlaceCardText(footer.rectTransform, 12f, 12f, -12f, 28f, false);
|
|
}
|
|
|
|
static Color GetRarityColor(string rarity)
|
|
{
|
|
switch (rarity)
|
|
{
|
|
case "Common": return new Color(0.1f, 0.12f, 0.14f, 0.98f);
|
|
case "Uncommon": return new Color(0.09f, 0.16f, 0.12f, 0.98f);
|
|
case "Rare": return new Color(0.08f, 0.13f, 0.2f, 0.98f);
|
|
case "Epic": return new Color(0.15f, 0.1f, 0.19f, 0.98f);
|
|
case "Legendary": return new Color(0.2f, 0.15f, 0.07f, 0.98f);
|
|
default: return new Color(0.1f, 0.11f, 0.14f, 0.98f);
|
|
}
|
|
}
|
|
|
|
void SelectOffer(UpgradeOffer offer)
|
|
{
|
|
if (offer.isFree)
|
|
ApplyFreeUpgrade(offer.freeType);
|
|
else
|
|
BuyPaidUpgrade(offer.paidType);
|
|
|
|
CompleteChoice();
|
|
}
|
|
|
|
void BuyPaidUpgrade(UpgradeCard.UpgradeType type)
|
|
{
|
|
int cost = upgradeCosts[type];
|
|
if (bits < cost || IsAtMaxStacks(type))
|
|
return;
|
|
|
|
bits -= cost;
|
|
upgradeLevels[type]++;
|
|
upgradeCosts[type] += Mathf.Max(1, Mathf.RoundToInt(cost * 0.45f));
|
|
ApplyTowerUpgrade(type);
|
|
UpdateBitsText();
|
|
}
|
|
|
|
void ApplyTowerUpgrade(UpgradeCard.UpgradeType type)
|
|
{
|
|
if (tower == null)
|
|
tower = FindAnyObjectByType<Tower>();
|
|
|
|
if (tower == null)
|
|
return;
|
|
|
|
switch (type)
|
|
{
|
|
case UpgradeCard.UpgradeType.ReinforcedPowder:
|
|
tower.shellDamageMultiplier *= 1.15f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.ExpandedPayload:
|
|
tower.splashRadius *= 1.12f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.AutoLoader:
|
|
tower.fireRate *= 0.9f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.HeavyCaliber:
|
|
tower.shellDamageMultiplier *= 1.25f;
|
|
tower.fireRate *= 1.08f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.ShockwaveShells:
|
|
tower.explosionKnockback += 0.12f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.ShrapnelRounds:
|
|
tower.shrapnelEdgeDamageMultiplier += 0.35f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.FragmentBurst:
|
|
tower.fragmentCount += 3;
|
|
break;
|
|
case UpgradeCard.UpgradeType.BurningDebris:
|
|
tower.burningGroundDuration += 2f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.ConcussiveImpact:
|
|
tower.concussiveSlowMultiplier = Mathf.Min(tower.concussiveSlowMultiplier, Mathf.Max(0.35f, 0.8f - 0.06f * upgradeLevels[type]));
|
|
tower.concussiveSlowDuration += 1f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.CraterMaker:
|
|
tower.craterDuration += 2.5f;
|
|
tower.craterSlowMultiplier = Mathf.Min(tower.craterSlowMultiplier, 0.7f);
|
|
break;
|
|
case UpgradeCard.UpgradeType.ChainDetonation:
|
|
tower.chainDetonationMultiplier += 0.2f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.SiegeShells:
|
|
tower.siegeShellStacks++;
|
|
break;
|
|
case UpgradeCard.UpgradeType.ArmorPiercingCore:
|
|
tower.directHitDamageMultiplier *= 1.25f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.DoubleCharge:
|
|
tower.doubleChargeChance += 0.2f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.SiegePlatform:
|
|
tower.siegePlatformStacks++;
|
|
break;
|
|
case UpgradeCard.UpgradeType.ExecutionShell:
|
|
tower.executionDamageMultiplier += 0.25f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.FinisherPayload:
|
|
tower.finisherDamageMultiplier += 0.25f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.StabilizedBarrel:
|
|
tower.projectileSpeedMultiplier *= 1.3f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.SmartTargeting:
|
|
tower.smartTargeting = true;
|
|
break;
|
|
case UpgradeCard.UpgradeType.RangefinderOptics:
|
|
tower.attackRange *= 1.18f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.DelayedFuse:
|
|
tower.delayedFuseSeconds += 0.08f;
|
|
tower.delayedFuseRadiusMultiplier *= 1.16f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.OverloadedChamber:
|
|
tower.shellDamageMultiplier *= 1.4f;
|
|
tower.fireRate *= 1.15f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.VolatileMunitions:
|
|
tower.volatileSecondaryExplosionMultiplier += 0.35f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.GlassCannonDesign:
|
|
tower.glassCannonDesign = true;
|
|
tower.shellDamageMultiplier *= 2.25f;
|
|
break;
|
|
case UpgradeCard.UpgradeType.ApocalypseRound:
|
|
tower.apocalypseRound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ApplyFreeUpgrade(FreeUpgradeType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case FreeUpgradeType.KillBonus:
|
|
bonusBitsPerKill++;
|
|
break;
|
|
case FreeUpgradeType.HitBonus:
|
|
hitBitChance += 0.4f;
|
|
break;
|
|
}
|
|
|
|
UpdateBitsText();
|
|
}
|
|
|
|
void CompleteChoice()
|
|
{
|
|
if (choiceOverlay != null)
|
|
Destroy(choiceOverlay);
|
|
|
|
choiceOverlay = null;
|
|
Time.timeScale = 1f;
|
|
|
|
Action callback = currentChoiceComplete;
|
|
currentChoiceComplete = null;
|
|
callback?.Invoke();
|
|
}
|
|
|
|
bool IsAtMaxStacks(UpgradeCard.UpgradeType type)
|
|
{
|
|
CardDefinition card = GetCard(type);
|
|
return card.maxStacks > 0 && upgradeLevels.TryGetValue(type, out int level) && level >= card.maxStacks;
|
|
}
|
|
|
|
void EnsureBitsText()
|
|
{
|
|
if (bitsText != null)
|
|
{
|
|
StyleBitsText();
|
|
return;
|
|
}
|
|
|
|
Canvas canvas = FindAnyObjectByType<Canvas>();
|
|
if (canvas == null)
|
|
{
|
|
GameObject canvasObject = new GameObject("GameUI", typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
|
|
canvas = canvasObject.GetComponent<Canvas>();
|
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
|
|
|
CanvasScaler scaler = canvasObject.GetComponent<CanvasScaler>();
|
|
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
|
scaler.referenceResolution = new Vector2(800f, 600f);
|
|
scaler.matchWidthOrHeight = 0.5f;
|
|
}
|
|
|
|
Transform existing = canvas.transform.Find("BitsCounter");
|
|
if (existing != null)
|
|
bitsText = existing.GetComponent<TextMeshProUGUI>();
|
|
|
|
if (bitsText == null)
|
|
{
|
|
GameObject textObject = new GameObject("BitsCounter", typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI));
|
|
RectTransform rect = textObject.GetComponent<RectTransform>();
|
|
rect.SetParent(canvas.transform, false);
|
|
bitsText = textObject.GetComponent<TextMeshProUGUI>();
|
|
}
|
|
|
|
StyleBitsText();
|
|
}
|
|
|
|
void UpdateBitsText()
|
|
{
|
|
EnsureBitsText();
|
|
bitsText.text = "BITS " + bits;
|
|
}
|
|
|
|
void StyleBitsText()
|
|
{
|
|
RectTransform rect = bitsText.GetComponent<RectTransform>();
|
|
if (rect != null)
|
|
{
|
|
rect.anchorMin = new Vector2(0f, 1f);
|
|
rect.anchorMax = new Vector2(0f, 1f);
|
|
rect.pivot = new Vector2(0f, 1f);
|
|
rect.anchoredPosition = new Vector2(24f, -24f);
|
|
rect.sizeDelta = new Vector2(170f, 42f);
|
|
}
|
|
|
|
bitsText.alignment = TextAlignmentOptions.Center;
|
|
bitsText.fontSize = 21f;
|
|
bitsText.fontStyle = FontStyles.Bold;
|
|
bitsText.color = new Color(0.98f, 0.87f, 0.32f, 1f);
|
|
bitsText.raycastTarget = false;
|
|
|
|
Outline outline = bitsText.GetComponent<Outline>();
|
|
if (outline == null)
|
|
outline = bitsText.gameObject.AddComponent<Outline>();
|
|
outline.effectColor = new Color(0f, 0f, 0f, 0.55f);
|
|
outline.effectDistance = new Vector2(1.5f, -1.5f);
|
|
}
|
|
|
|
GameObject CreateOverlay(bool freeFallback)
|
|
{
|
|
Canvas canvas = bitsText.GetComponentInParent<Canvas>();
|
|
GameObject overlay = new GameObject("WaveUpgradeOverlay", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
|
|
RectTransform rect = overlay.GetComponent<RectTransform>();
|
|
rect.SetParent(canvas.transform, false);
|
|
rect.anchorMin = Vector2.zero;
|
|
rect.anchorMax = Vector2.one;
|
|
rect.offsetMin = Vector2.zero;
|
|
rect.offsetMax = Vector2.zero;
|
|
rect.SetAsLastSibling();
|
|
|
|
Image image = overlay.GetComponent<Image>();
|
|
image.color = new Color(0f, 0f, 0f, 0.74f);
|
|
image.raycastTarget = true;
|
|
|
|
string titleText = freeFallback ? "LOW BITS: CHOOSE SUPPLY BOOST" : "CHOOSE CANNON UPGRADE";
|
|
TextMeshProUGUI title = CreateText("Title", rect, titleText, 28f, FontStyles.Bold, TextAlignmentOptions.Center);
|
|
RectTransform titleRect = title.rectTransform;
|
|
titleRect.anchorMin = new Vector2(0.5f, 0.5f);
|
|
titleRect.anchorMax = new Vector2(0.5f, 0.5f);
|
|
titleRect.pivot = new Vector2(0.5f, 0.5f);
|
|
titleRect.anchoredPosition = new Vector2(0f, 138f);
|
|
titleRect.sizeDelta = new Vector2(640f, 42f);
|
|
|
|
TextMeshProUGUI bitsLabel = CreateText("Bits", rect, "BITS " + bits, 18f, FontStyles.Bold, TextAlignmentOptions.Center);
|
|
bitsLabel.color = new Color(0.98f, 0.87f, 0.32f, 1f);
|
|
RectTransform bitsRect = bitsLabel.rectTransform;
|
|
bitsRect.anchorMin = new Vector2(0.5f, 0.5f);
|
|
bitsRect.anchorMax = new Vector2(0.5f, 0.5f);
|
|
bitsRect.pivot = new Vector2(0.5f, 0.5f);
|
|
bitsRect.anchoredPosition = new Vector2(0f, 104f);
|
|
bitsRect.sizeDelta = new Vector2(220f, 30f);
|
|
|
|
return overlay;
|
|
}
|
|
|
|
static CardDefinition Card(UpgradeCard.UpgradeType type, string title, string description, string rarity, int maxStacks, int baseCost)
|
|
{
|
|
return new CardDefinition
|
|
{
|
|
type = type,
|
|
title = title,
|
|
description = description,
|
|
rarity = rarity,
|
|
maxStacks = maxStacks,
|
|
baseCost = baseCost
|
|
};
|
|
}
|
|
|
|
static CardDefinition GetCard(UpgradeCard.UpgradeType type)
|
|
{
|
|
foreach (CardDefinition card in CannonCards)
|
|
{
|
|
if (card.type == type)
|
|
return card;
|
|
}
|
|
|
|
return CannonCards[0];
|
|
}
|
|
|
|
static RectTransform CreateRect(string name, Transform parent)
|
|
{
|
|
GameObject obj = new GameObject(name, typeof(RectTransform));
|
|
RectTransform rect = obj.GetComponent<RectTransform>();
|
|
rect.SetParent(parent, false);
|
|
return rect;
|
|
}
|
|
|
|
static TextMeshProUGUI CreateText(string name, Transform parent, string text, float fontSize, FontStyles style, TextAlignmentOptions alignment)
|
|
{
|
|
GameObject obj = new GameObject(name, typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI));
|
|
RectTransform rect = obj.GetComponent<RectTransform>();
|
|
rect.SetParent(parent, false);
|
|
|
|
TextMeshProUGUI label = obj.GetComponent<TextMeshProUGUI>();
|
|
label.text = text;
|
|
label.fontSize = fontSize;
|
|
label.fontStyle = style;
|
|
label.alignment = alignment;
|
|
label.color = new Color(0.9f, 0.93f, 0.98f, 1f);
|
|
label.textWrappingMode = TextWrappingModes.Normal;
|
|
label.raycastTarget = false;
|
|
return label;
|
|
}
|
|
|
|
static void PlaceCardText(RectTransform rect, float left, float top, float right, float height, bool fromTop)
|
|
{
|
|
rect.anchorMin = fromTop ? new Vector2(0f, 1f) : new Vector2(0f, 0f);
|
|
rect.anchorMax = fromTop ? new Vector2(1f, 1f) : new Vector2(1f, 0f);
|
|
rect.pivot = fromTop ? new Vector2(0.5f, 1f) : new Vector2(0.5f, 0f);
|
|
rect.offsetMin = new Vector2(left, fromTop ? -height : top);
|
|
rect.offsetMax = new Vector2(right, fromTop ? top : top + height);
|
|
}
|
|
|
|
static string ToRoman(int number)
|
|
{
|
|
string[] numerals = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X" };
|
|
return number < 1 || number > 10 ? number.ToString() : numerals[number - 1];
|
|
}
|
|
}
|