hostile-takeover/m/unit.cs
2014-07-06 17:47:28 -07:00

493 lines
14 KiB
C#

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;
using SpiffLib;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
using System.Drawing.Design;
using System.ComponentModel;
namespace m {
// Wrappers for graceful future versioning
[Serializable]
public class GalaxMiner : MobileUnit {
public GalaxMiner(Side side, int tx, int ty) : base(side, tx, ty) {
m_aggr = Aggressiveness.Coward;
}
public GalaxMiner(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
m_aggr = Aggressiveness.Coward;
}
public GalaxMiner(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public GalaxMiner(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
try {
m_aggr = (Aggressiveness)info.GetInt32("Aggressiveness");
} catch (SerializationException) {
m_aggr = Aggressiveness.Coward;
}
}
}
[Serializable]
public class ShortRangeInfantry : MobileUnit {
public ShortRangeInfantry(Side side, int tx, int ty) : base(side, tx, ty) {
}
public ShortRangeInfantry(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public ShortRangeInfantry(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public ShortRangeInfantry(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
[Serializable]
public class LongRangeInfantry : MobileUnit {
public LongRangeInfantry(Side side, int tx, int ty) : base(side, tx, ty) {
}
public LongRangeInfantry(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public LongRangeInfantry(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public LongRangeInfantry(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
[Serializable]
public class TakeoverSpecialist : MobileUnit {
public TakeoverSpecialist(Side side, int tx, int ty) : base(side, tx, ty) {
m_aggr = Aggressiveness.Coward;
}
public TakeoverSpecialist(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
m_aggr = Aggressiveness.Coward;
}
public TakeoverSpecialist(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public TakeoverSpecialist(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
try {
m_aggr = (Aggressiveness)info.GetInt32("Aggressiveness");
} catch (SerializationException) {
m_aggr = Aggressiveness.Coward;
}
}
}
[Serializable]
public class LightTank : MobileUnit {
public LightTank(Side side, int tx, int ty) : base(side, tx, ty) {
}
public LightTank(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public LightTank(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public LightTank(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
[Serializable]
public class MediumTank : MobileUnit {
public MediumTank(Side side, int tx, int ty) : base(side, tx, ty) {
}
public MediumTank(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public MediumTank(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public MediumTank(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
[Serializable]
public class MachineGunVehicle : MobileUnit {
public MachineGunVehicle(Side side, int tx, int ty) : base(side, tx, ty) {
}
public MachineGunVehicle(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public MachineGunVehicle(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public MachineGunVehicle(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
[Serializable]
public class RocketVehicle : MobileUnit {
public RocketVehicle(Side side, int tx, int ty) : base(side, tx, ty) {
}
public RocketVehicle(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public RocketVehicle(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public RocketVehicle(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
[Serializable]
public class MobileHeadquarters : MobileUnit {
public MobileHeadquarters(Side side, int tx, int ty) : base(side, tx, ty) {
m_aggr = Aggressiveness.Coward;
}
public MobileHeadquarters(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
m_aggr = Aggressiveness.Coward;
}
public MobileHeadquarters(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public MobileHeadquarters(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
try {
m_aggr = (Aggressiveness)info.GetInt32("Aggressiveness");
} catch (SerializationException) {
m_aggr = Aggressiveness.Coward;
}
}
}
[Serializable]
public class Artillery : MobileUnit {
public Artillery(Side side, int tx, int ty) : base(side, tx, ty) {
}
public Artillery(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public Artillery(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public Artillery(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
[Serializable]
public class Andy : MobileUnit {
public Andy(Side side, int tx, int ty) : base(side, tx, ty) {
}
public Andy(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public Andy(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public Andy(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
[Serializable]
public class Fox : MobileUnit {
public Fox(Side side, int tx, int ty) : base(side, tx, ty) {
}
public Fox(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty, aggr, cab) {
}
public Fox(string strName, string strValue, int txOrigin, int tyOrigin) :
base(strName, strValue, txOrigin, tyOrigin) {
}
public Fox(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
}
}
public enum Aggressiveness {
Coward,
Pacifist,
SelfDefense,
Defender,
Pitbull
}
[Serializable]
public class MobileUnit : Unit {
protected Aggressiveness m_aggr;
public MobileUnit(Side side, int tx, int ty) : base(side, tx, ty) {
m_aggr = Aggressiveness.Defender;
m_cab = new GuardUnitAction();
}
public MobileUnit(Side side, int tx, int ty, Aggressiveness aggr, CaBase cab) : base(side, tx, ty) {
m_aggr = aggr;
m_cab = cab;
}
public MobileUnit(SerializationInfo info, StreamingContext ctx) : base(info, ctx) {
try {
m_aggr = (Aggressiveness)info.GetInt32("Aggressiveness");
} catch (SerializationException) {
m_aggr = Aggressiveness.Defender;
}
try {
m_cab = (CaBase)info.GetValue("Action", typeof(CaBase));
} catch (SerializationException) {
m_cab = new GuardUnitAction();
}
Init();
}
public MobileUnit(string strName, string strValue, int txOrigin,
int tyOrigin) : base(strName, strValue, txOrigin, tyOrigin) {
Regex re = new Regex(@"^(?<gt>\d+),(?<side>\d+),(?<tx>\d+),(?<ty>\d+),(?<wf>\d+),(?<health>\d+),(?<aggr>\d+)(,\{(?<cab>.*)\})?$");
Match m = re.Match(strValue);
m_aggr = (Aggressiveness)int.Parse(m.Groups["aggr"].Value);
if (m.Groups["cab"] != null) {
m_cab = UnitActionLoader.LoadIni(m.Groups["cab"].Value);
}
}
public override Ini.Property GetIniProperty(int txOrigin, int tyOrigin) {
// For example: nil=kgtRocketVehicle,side,38,120,0,100,knAggressivenessPitbull,{knGuardAreaAction,2}
Ini.Property prp = base.GetIniProperty(txOrigin, tyOrigin);
prp.Value += ",knAggressiveness" + m_aggr.ToString();
if (m_cab != null)
prp.Value += ",{" + m_cab.ToSaveString() + "}";
return prp;
}
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
base.GetObjectData(info, context);
info.AddValue("Aggressiveness", m_aggr);
info.AddValue("Action", m_cab);
}
public override Object Clone() {
Object[] aobj = { m_side, (int)m_tx, (int)m_ty, m_aggr, m_cab.Clone() };
return (Object)System.Activator.CreateInstance(GetType(), aobj);
}
[Category("Behavior")]
public Aggressiveness Aggressiveness {
get {
return m_aggr;
}
set {
if (m_aggr != value) {
m_aggr = value;
OnPropertyChanged(this, "Aggressiveness");
}
}
}
[EditorAttribute(typeof(ActionEditor), typeof(UITypeEditor)), Category("Behavior")]
public CaBase Action {
get {
return m_cab;
}
set {
if (m_cab != value) {
m_cab = value;
OnPropertyChanged(this, "Action");
}
}
}
}
public class ActionEditor : UITypeEditor {
// Indicates that the UITypeEditor provides a form-based (modal) dialog.
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
return UITypeEditorEditStyle.Modal;
}
// Displays the UI for value selection.
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {
CaBase cab = (CaBase)value;
cab = CaNew.DoModal(cab.Clone(), "Modify Action", "UnitAction");
return cab == null ? value : cab;
}
}
[Serializable]
public class Unit : MapItem, ISerializable {
protected Side m_side;
protected GobImage m_gimg;
protected CaBase m_cab;
protected int m_nHealth;
public Unit(Side side) {
m_side = side;
Init();
}
public Unit(Side side, int tx, int ty) {
m_tx = tx;
m_ty = ty;
m_side = side;
Init();
}
public Unit(SerializationInfo info, StreamingContext ctx) : base (info, ctx) {
m_side = (Side)info.GetInt32("Side");
try {
m_nHealth = info.GetInt32("Health");
} catch (SerializationException) {
m_nHealth = 100;
}
Init();
}
public Unit(string strName, string strValue, int txOrigin, int tyOrigin) {
Regex re = new Regex(@"^(?<gt>\d+),(?<side>\d+),(?<tx>\d+),(?<ty>\d+),(?<wf>\d+),(?<health>\d+).*$");
Match m = re.Match(strValue);
m_side = (Side)int.Parse(m.Groups["side"].Value);
m_tx = int.Parse(m.Groups["tx"].Value) + txOrigin;
m_ty = int.Parse(m.Groups["ty"].Value) + tyOrigin;
m_nHealth = int.Parse(m.Groups["health"].Value);
Init();
}
public override Ini.Property GetIniProperty(int txOrigin, int tyOrigin) {
// For example: nil=gobtype,side,38,120,0,100
string strValue = "kgt" + GetType().Name + ",";
strValue += "k" + m_side.ToString() + ",";
strValue += (m_tx - txOrigin).ToString() + "," + (m_ty - tyOrigin).ToString();
strValue += ",0," + m_nHealth;
return new Ini.Property("nil", strValue);
}
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
base.GetObjectData(info, context);
info.AddValue("Side", m_side);
info.AddValue("Health", m_nHealth);
}
protected virtual void Init() {
m_gimg = Globals.GetGobImage(GetType().Name, true);
if (m_gimg == null)
throw new Exception("Cannot find image for gob " + GetType().Name);
}
public Side Side {
get {
return m_side;
}
set {
if (m_side != value) {
m_side = value;
OnPropertyChanged(this, "Side");
}
}
}
public int Health {
get {
return m_nHealth;
}
set {
m_nHealth = value;
OnPropertyChanged(this, "Health");
}
}
public virtual Point GetTileOrigin(Size sizTile) {
// Units have an offset of mid-tile (to place their origin in the tile center, as per game code)
return new Point(sizTile.Width / 2, sizTile.Height / 2);
}
public virtual Size GetSize(Size sizTile) {
return m_gimg.GetSize(sizTile);
}
// IMapItem
public override Bitmap GetBitmap(Size sizTile, TemplateDoc tmpd) {
Bitmap[] abm = m_gimg.GetBitmapSides(sizTile);
return abm[(int)m_side];
}
public override Point GetCenterPoint(Size sizTile) {
Point ptTOrigin = GetTileOrigin(sizTile);
Point ptGobOrigin = m_gimg.GetOrigin(sizTile);
Size sizGob = m_gimg.GetSize(sizTile);
int x = (int)m_tx * sizTile.Width + ptTOrigin.X - ptGobOrigin.X;
int y = (int)m_ty * sizTile.Height + ptTOrigin.Y - ptGobOrigin.Y;
return new Point(x + sizGob.Width / 2, y + sizGob.Height / 2);
}
public override Rectangle GetBoundingRectAt(int x, int y, Size sizTile, TemplateDoc tmpd) {
Point ptTOrigin = GetTileOrigin(sizTile);
Point ptGobOrigin = m_gimg.GetOrigin(sizTile);
int xT = x + ptTOrigin.X - ptGobOrigin.X;
int yT = y + ptTOrigin.Y - ptGobOrigin.Y;
Size siz = GetSize(sizTile);
return new Rectangle(xT, yT, siz.Width, siz.Height);
}
public override bool HitTest(int x, int y, Size sizTile, TemplateDoc tmpd) {
Point ptTOrigin = GetTileOrigin(sizTile);
Point ptGobOrigin = m_gimg.GetOrigin(sizTile);
Size sizGob = m_gimg.GetSize(sizTile);
int xT = x - ((int)m_tx * sizTile.Width + ptTOrigin.X - ptGobOrigin.X);
int yT = y - ((int)m_ty * sizTile.Height + ptTOrigin.Y - ptGobOrigin.Y);
if (xT > 0 && xT < sizGob.Width && yT > 0 && yT < sizGob.Height) {
Bitmap[] abmGob = m_gimg.GetBitmapSides(sizTile);
return abmGob[(int)m_side].GetPixel(xT, yT) != Color.Transparent;
}
return false;
}
public override Object Clone() {
Object[] aobj = { m_side, (int)m_tx, (int)m_ty };
return (Object)System.Activator.CreateInstance(GetType(), aobj);
}
public override void Draw(Graphics g, int x, int y, Size sizTile, TemplateDoc tmpd, LayerType layer, bool fSelected) {
Point ptTOrigin = GetTileOrigin(sizTile);
Point ptGobOrigin = m_gimg.GetOrigin(sizTile);
x += ptTOrigin.X - ptGobOrigin.X;
y += ptTOrigin.Y - ptGobOrigin.Y;
if (layer == LayerType.DepthSorted) {
Bitmap bm = m_gimg.GetBitmapSides(sizTile)[(int)m_side];
if (fSelected) {
Rectangle rcDst = new Rectangle(x, y, bm.Width, bm.Height);
ImageAttributes attr = new ImageAttributes();
attr.SetGamma(0.5f);
g.DrawImage(bm, rcDst, 0, 0, bm.Width, bm.Height, GraphicsUnit.Pixel, attr);
} else {
g.DrawImage(bm, x, y);
}
}
}
}
}