using System; using System.Collections.Generic; using UnityEngine; // МОСТ между картой мира Саши (армия = просто число "солдат") и нашей армией (4 типа войск в GameProgress). // - "Солдаты дома" = все наши воины в городе. // - При отправке похода берём воинов из всех типов пропорционально и запоминаем состав похода. // - При возвращении выживших раздаём обратно по тем же типам в той же пропорции. // Благодаря этому одна армия на всю игру: наняли в казармах -> можно отправить и с нашей карты (МИР), // и с большой карты мира (сцена WorldMap). public static class ArmyBridge { [Serializable] public class MarchUnits { public int marchId; public int[] units = new int[4]; } static ProgressData D { get { return GameProgress.Instance.Data; } } public static int SoldiersAtHome { get { return GameProgress.Instance.TotalTroops; } } // Забрать count воинов из города в поход marchId public static bool Take(int marchId, int count) { var troops = D.troops; int total = 0; foreach (var t in troops) total += t; if (count <= 0 || count > total) return false; // пропорционально, остаток раздаём по самым многочисленным типам var taken = new int[troops.Length]; int given = 0; var remainders = new List>(); for (int i = 0; i < troops.Length; i++) { float exact = (float)count * troops[i] / total; taken[i] = Mathf.Min(troops[i], Mathf.FloorToInt(exact)); given += taken[i]; remainders.Add(new KeyValuePair(i, exact - taken[i])); } remainders.Sort((a, b) => b.Value.CompareTo(a.Value)); for (int k = 0; given < count && k < remainders.Count * 2; k++) { int i = remainders[k % remainders.Count].Key; if (taken[i] < troops[i]) { taken[i]++; given++; } } for (int i = 0; i < troops.Length; i++) troops[i] -= taken[i]; var entry = new MarchUnits { marchId = marchId }; for (int i = 0; i < 4 && i < taken.Length; i++) entry.units[i] = taken[i]; D.sashaMarchUnits.RemoveAll(e => e.marchId == marchId); D.sashaMarchUnits.Add(entry); GameProgress.Instance.MarkChanged(); return true; } // Вернуть survivors выживших из похода marchId по типам войск public static void Return(int marchId, int survivors) { var entry = D.sashaMarchUnits.Find(e => e.marchId == marchId); var troops = D.troops; if (entry == null) { troops[0] += Mathf.Max(0, survivors); // состав неизвестен (старое сохранение) -- считаем пехотой } else { int sent = 0; foreach (var u in entry.units) sent += u; int back = 0; for (int i = 0; i < entry.units.Length && i < troops.Length; i++) { int n = sent > 0 ? Mathf.FloorToInt((float)survivors * entry.units[i] / sent) : 0; troops[i] += n; back += n; } // остаток округления -- в самый многочисленный тип похода int best = 0; for (int i = 1; i < entry.units.Length; i++) if (entry.units[i] > entry.units[best]) best = i; troops[best] += Mathf.Max(0, survivors - back); D.sashaMarchUnits.Remove(entry); } GameProgress.Instance.MarkChanged(); } }