XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

AshfallFrontier

【Unity】灰烬边境,一款生存策略游戏

公开
关注 0 Fork 0 Star 0
UTF-8
using System;
using System.Collections.Generic;
using System.Linq;

namespace Ashfall.Core
{
    [Serializable]
    public class ItemStack { public string id; public int amount; }

    [Serializable]
    public class Inventory
    {
        public List<ItemStack> items = new List<ItemStack>();
        public int capacity = 10000;
        public int Count(string id) => items.Where(i => i.id == id).Sum(i => i.amount);
        public int Total => items.Sum(i => i.amount);
        public bool Has(string id, int n) => n > 0 && Count(id) >= n;
        public bool Add(string id, int n)
        {
            if (string.IsNullOrEmpty(id) || n <= 0 || (long)Total + n > capacity) return false;
            var stack = items.Find(i => i.id == id);
            if (stack == null) items.Add(new ItemStack { id = id, amount = n });
            else stack.amount += n;
            return true;
        }
        public bool Take(string id, int n)
        {
            if (!Has(id, n)) return false;
            int remaining = n;
            foreach (var stack in items.Where(i => i.id == id))
            { int take = Math.Min(stack.amount, remaining); stack.amount -= take; remaining -= take; }
            items.RemoveAll(i => i.amount == 0);
            return true;
        }
        public static bool Transfer(Inventory from, Inventory to, string id, int n)
        {
            if (from == null || to == null || ReferenceEquals(from, to) || n <= 0 || !from.Has(id, n)
                || (long)to.Total + n > to.capacity) return false;
            from.Take(id, n); to.Add(id, n); return true;
        }
    }

    [Serializable]
    public class Location
    {
        public string spaceId = "world";
        public int floor;
        public V2 position;
        public float height;
        public Location Copy() => new Location { spaceId = spaceId, floor = floor, position = position, height = height };
        public bool SameFloor(Location other) => other != null && spaceId == other.spaceId && floor == other.floor;
    }

    [Serializable]
    public class PlayerInput
    {
        public int sequence;
        public V2 move, aim;
        public bool fire, secondary, sprint, brake;
    }

    [Serializable]
    public class PlayerState
    {
        public string id, name;
        public string reconnectTokenHash = "";
        public Species species;
        public BroodForm broodForm = BroodForm.Worm;
        public Location location = new Location();
        public Inventory inventory = new Inventory { capacity = 600 };
        public bool connected;
        public float health = 250, maxHealth = 250, energy = 100;
        public int humanLevel = 1, broodLevel = 1, experience;
        public string stationId = "", preferredStationId = "", transitionId = "";
        public float transitionProgress, heading;
        public double portalReadyAt, shotReadyAt, abilityReadyAt, burrowUntil, wingUntil, buffUntil;
        public long lastCommand;
        public int acknowledgedInput;
        public PlayerInput input = new PlayerInput();
        public double lastInputAt;
        public int kills;
        public int Level => species == Species.Human ? humanLevel : broodLevel;
        public bool IsWorm => species == Species.Brood && broodForm == BroodForm.Worm;
    }

    [Serializable]
    public class WallState { public string id; public Box2 bounds; public float height = 3; public bool open; }

    [Serializable]
    public class FloorState
    {
        public int index;
        public string name;
        public Box2 bounds;
        public List<WallState> walls = new List<WallState>();
        public bool playerBuilt;
    }

    [Serializable]
    public class SpaceState
    {
        public string id, name, ownerId;
        public SpaceKind kind;
        public Family family;
        public V2 worldAnchor;
        public List<FloorState> floors = new List<FloorState>();
    }

    [Serializable]
    public class PortalState
    {
        public string id, name, ownerId = "";
        public Location from = new Location(), to = new Location();
        public bool stairs, requiresResearch;
        public float seconds = .3f;
    }

    [Serializable]
    public class StationState
    {
        public string id, name, playerId = "";
        public StationRole role;
        public Location location = new Location();
        public int weaponGroup;
    }

    [Serializable]
    public class HardpointState
    {
        public string id, moduleId = "";
        public int size = 1, group;
        public float arc = 360, arcCenter;
        public float aimHeading;
        public double readyAt;
        public float health = 100;
    }

    [Serializable]
    public class VehicleState
    {
        public string id, definitionId, name, spaceId;
        public Family family;
        public V2 position;
        public float heading, speed, maxSpeed = 9, length = 14, width = 8;
        public float hull = 1000, maxHull = 1000, engine = 100, power = 100;
        public float energy = 100, maxEnergy = 100, massLimit = 80, powerBudget = 20;
        public bool flying, cruise, doorOpen = true;
        public FlightMode flightMode;
        public string dockedTo = "", berthId = "";
        public Inventory cargo = new Inventory { capacity = 4000 };
        public List<StationState> stations = new List<StationState>();
        public List<HardpointState> hardpoints = new List<HardpointState>();
        public V2 DoorPosition => position + new V2(0, -length / 2 - .8f).Rotate(heading);
        public float Altitude => flightMode == FlightMode.Ground ? 0 : flightMode == FlightMode.Low ? 6 : 24;
    }

    [Serializable]
    public class ProductionJob
    {
        public string id, recipeId, outputId;
        public int outputAmount;
        public float remaining;
    }

    [Serializable]
    public class FacilityState
    {
        public string id, name, ownerId;
        public FacilityKind kind;
        public Family family;
        public Location location = new Location();
        public bool powered = true;
        public int level = 1;
        public float health = 100;
        public List<ProductionJob> jobs = new List<ProductionJob>();
    }

    [Serializable]
    public class BuildPiece
    {
        public string id, ownerId;
        public Location location = new Location();
        public PieceKind kind;
        public int rotation;
        public Family family;
    }

    [Serializable]
    public class EnemyState
    {
        public string id;
        public Location location = new Location();
        public float health = 100, maxHealth = 100;
        public bool boss;
        public double attackReadyAt;
    }

    [Serializable]
    public class ResourceState
    {
        public string id, itemId;
        public Location location = new Location();
        public int amount;
    }

    [Serializable]
    public class ShotEvent
    {
        public int id;
        public string spaceId;
        public int floor;
        public V2 from, to;
        public float height;
        public Family family;
        public double expiresAt;
    }

    [Serializable]
    public class WorldState
    {
        public const int CurrentVersion = 1;
        public int version = CurrentVersion, seed = 7616, tick, nextId = 1;
        public double time;
        public bool bossDefeated;
        public Inventory warehouse = new Inventory { capacity = 20000 };
        public List<string> research = new List<string>();
        public List<PlayerState> players = new List<PlayerState>();
        public List<SpaceState> spaces = new List<SpaceState>();
        public List<PortalState> portals = new List<PortalState>();
        public List<VehicleState> vehicles = new List<VehicleState>();
        public List<FacilityState> facilities = new List<FacilityState>();
        public List<BuildPiece> pieces = new List<BuildPiece>();
        public List<EnemyState> enemies = new List<EnemyState>();
        public List<ResourceState> resources = new List<ResourceState>();
        public List<ShotEvent> shots = new List<ShotEvent>();
        public string NewId(string prefix) => prefix + "-" + nextId++;
        public PlayerState Player(string id) => players.Find(p => p.id == id);
        public SpaceState Space(string id) => spaces.Find(s => s.id == id);
        public FloorState Floor(Location l) => Space(l.spaceId)?.floors.Find(f => f.index == l.floor);
        public VehicleState Vehicle(string id) => vehicles.Find(v => v.id == id);
        public VehicleState VehicleForSpace(string id) => vehicles.Find(v => v.spaceId == id);
    }

    [Serializable]
    public class GameCommand
    {
        public long sequence;
        public CommandKind kind;
        public string targetId = "", value = "", slot = "";
        public V2 position;
        public int floor, rotation, amount = 1;
        public PieceKind piece;
    }
}