CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

Infantry.cs (4968B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // The Command & Conquer Map Editor and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // The Command & Conquer Map Editor and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 using MobiusEditor.Interface;
     16 using System;
     17 using System.Collections.Generic;
     18 using System.ComponentModel;
     19 using System.Drawing;
     20 using System.Linq;
     21 using System.Numerics;
     22 using System.Runtime.CompilerServices;
     23 
     24 namespace MobiusEditor.Model
     25 {
     26     public enum InfantryStoppingType
     27     {
     28         Center = 0,
     29         UpperLeft = 1,
     30         UpperRight = 2,
     31         LowerLeft = 3,
     32         LowerRight = 4
     33     }
     34 
     35     public class Infantry : INotifyPropertyChanged, ICloneable
     36     {
     37         public event PropertyChangedEventHandler PropertyChanged;
     38 
     39         public InfantryGroup InfantryGroup { get; set; }
     40 
     41         private InfantryType type;
     42         public InfantryType Type { get => type; set => SetField(ref type, value); }
     43 
     44         private HouseType house;
     45         public HouseType House { get => house; set => SetField(ref house, value); }
     46 
     47         private int strength;
     48         public int Strength { get => strength; set => SetField(ref strength, value); }
     49 
     50         private DirectionType direction;
     51         public DirectionType Direction { get => direction; set => SetField(ref direction, value); }
     52 
     53         private string mission;
     54         public string Mission { get => mission; set => SetField(ref mission, value); }
     55 
     56         private string trigger = Model.Trigger.None;
     57         public string Trigger { get => trigger; set => SetField(ref trigger, value); }
     58 
     59         public Color Tint { get; set; } = Color.White;
     60 
     61         public Infantry(InfantryGroup infantryGroup)
     62         {
     63             InfantryGroup = infantryGroup;
     64         }
     65 
     66         public Infantry Clone()
     67         {
     68             return new Infantry(InfantryGroup)
     69             {
     70                 Type = Type,
     71                 House = House,
     72                 Strength = Strength,
     73                 Direction = Direction,
     74                 Trigger = Trigger,
     75                 Mission = Mission,
     76             };
     77         }
     78     
     79         protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
     80         {
     81             if (EqualityComparer<T>.Default.Equals(field, value))
     82             {
     83                 return false;
     84             }
     85             field = value;
     86             OnPropertyChanged(propertyName);
     87             return true;
     88         }
     89 
     90         protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     91 
     92         object ICloneable.Clone()
     93         {
     94             return Clone();
     95         }
     96     }
     97 
     98     public class InfantryGroup : ICellOverlapper, ICellOccupier
     99     {
    100         private static readonly Point[] stoppingLocations = new Point[Globals.NumInfantryStops];
    101 
    102         public Rectangle OverlapBounds => new Rectangle(-1, -1, 3, 3);
    103 
    104         public bool[,] OccupyMask => new bool[1, 1] { { true } };
    105 
    106         public readonly Infantry[] Infantry = new Infantry[Globals.NumInfantryStops];
    107 
    108         static InfantryGroup()
    109         {
    110             stoppingLocations[(int)InfantryStoppingType.Center] = new Point(Globals.PixelWidth / 2, Globals.PixelHeight / 2);
    111             stoppingLocations[(int)InfantryStoppingType.UpperLeft] = new Point(Globals.PixelWidth / 4, Globals.PixelHeight / 4);
    112             stoppingLocations[(int)InfantryStoppingType.UpperRight] = new Point(3 * Globals.PixelWidth / 4, Globals.PixelHeight / 4);
    113             stoppingLocations[(int)InfantryStoppingType.LowerLeft] = new Point(Globals.PixelWidth / 4, 3 * Globals.PixelHeight / 4);
    114             stoppingLocations[(int)InfantryStoppingType.LowerRight] = new Point(3 * Globals.PixelWidth / 4, 3 * Globals.PixelHeight / 4);
    115         }
    116 
    117         public static IEnumerable<InfantryStoppingType> ClosestStoppingTypes(Point subPixel)
    118         {
    119             var stoppingDistances = new (InfantryStoppingType type, float dist)[stoppingLocations.Length];
    120             for (int i = 0; i < stoppingDistances.Length; ++i)
    121             {
    122                 stoppingDistances[i] = ((InfantryStoppingType)i, new Vector2(subPixel.X - stoppingLocations[i].X, subPixel.Y - stoppingLocations[i].Y).LengthSquared());
    123             }
    124             return stoppingDistances.OrderBy(sd => sd.dist).Select(sd => sd.type);
    125         }
    126     }
    127 }