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

334 lines
7.9 KiB
C#

using System;
using System.Collections;
using SpiffLib;
namespace m
{
// Capitalized this way on purpose for ToString() niceness
public enum Side {
[DisplayName("neutral")] sideNeutral = 0,
[DisplayName("side 1")] side1,
[DisplayName("side 2")] side2,
[DisplayName("side 3")] side3,
[DisplayName("side 4")] side4
};
[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]
class DisplayNameAttribute : Attribute {
private string m_strDisplayName;
public DisplayNameAttribute(string strName) {
m_strDisplayName = strName;
}
public string DisplayName {
get {
return m_strDisplayName;
}
set {
m_strDisplayName = value;
}
}
}
[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = false)]
class DescriptionAttribute : Attribute {
private string m_strDescription;
public DescriptionAttribute(string strDescription) {
m_strDescription = strDescription;
}
public string Description {
get {
return m_strDescription;
}
set {
m_strDescription = value;
}
}
}
[Serializable]
public class TriggerManager
{
ArrayList m_alsTriggers;
ArrayList[] m_aalsSideTriggers;
bool m_fModified;
public TriggerManager()
{
m_fModified = false;
m_alsTriggers = new ArrayList();
m_aalsSideTriggers = new ArrayList[Enum.GetValues(typeof(Side)).Length];
for (int n = 0; n < m_aalsSideTriggers.Length; n++)
m_aalsSideTriggers[n] = new ArrayList();
}
public ArrayList Triggers {
get {
return m_alsTriggers;
}
}
void SetModified() {
m_fModified = true;
}
public void ClearModified() {
m_fModified = false;
}
public bool IsModified() {
return m_fModified;
}
public Trigger[] GetTriggerList(Side side) {
ArrayList als = (ArrayList)m_aalsSideTriggers[(int)side];
return (Trigger[])als.ToArray(typeof(Trigger));
}
public void AddTrigger(Trigger tgr) {
m_alsTriggers.Add(tgr);
foreach(Side side in Enum.GetValues(typeof(Side))) {
if ((tgr.Sides & SideToMask(side)) != 0) {
ArrayList als = (ArrayList)m_aalsSideTriggers[(int)side];
als.Add(tgr);
}
}
SetModified();
}
public void RemoveTrigger(Trigger tgr) {
m_alsTriggers.Remove(tgr);
foreach (Side side in Enum.GetValues(typeof(Side))) {
if ((tgr.Sides & SideToMask(side)) != 0) {
ArrayList als = (ArrayList)m_aalsSideTriggers[(int)side];
als.Remove(tgr);
}
}
SetModified();
}
public void ModifyTrigger(Trigger tgrModify, Trigger tgr) {
int n = m_alsTriggers.IndexOf(tgrModify);
if (n >= 0)
m_alsTriggers[n] = tgr;
foreach(Side side in Enum.GetValues(typeof(Side))) {
ArrayList als = (ArrayList)m_aalsSideTriggers[(int)side];
if ((SideToMask(side) & tgr.Sides) != 0) {
n = als.IndexOf(tgrModify);
if (n >= 0) {
als[n] = tgr;
} else {
als.Add(tgr);
}
} else {
als.Remove(tgrModify);
}
}
SetModified();
}
public int MoveUpTrigger(Side side, Trigger tgr) {
ArrayList als = (ArrayList)m_aalsSideTriggers[(int)side];
int n = als.IndexOf(tgr);
if (n > 0) {
als.Remove(tgr);
als.Insert(n - 1, tgr);
SetModified();
return n - 1;
}
return -1;
}
public int MoveDownTrigger(Side side, Trigger tgr) {
ArrayList als = (ArrayList)m_aalsSideTriggers[(int)side];
int n = als.IndexOf(tgr);
if (n != -1 && n < als.Count - 1) {
als.Remove(tgr);
als.Insert(n + 1, tgr);
SetModified();
return n + 1;
}
return -1;
}
public int SideToMask(Side side) {
return (1 << (int)side);
}
public Side[] GetTriggerSides() {
int nfMask = GetSidesMask();
ArrayList alsSides = new ArrayList();
foreach (Side side in Enum.GetValues(typeof(Side))) {
if ((nfMask & SideToMask(side)) != 0)
alsSides.Add(side);
}
return (Side[])alsSides.ToArray(typeof(Side));
}
public int GetSidesMask() {
int nfMask = 0;
foreach (Trigger tgr in m_alsTriggers) {
nfMask |= tgr.Sides;
}
return nfMask;
}
public Ini.Section GetIniSection(bool fDemoCheckTrigger) {
// If asked create a trigger causes mission failure if running on
// demo version side1
bool fModifiedSave = m_fModified;
Trigger tgrDemo = new Trigger();
if (fDemoCheckTrigger) {
// condition: persistent variable $demo is exactly 1
// action: end mission: lose
// Condition
tgrDemo.Sides = SideToMask(Side.side1);
TestPvarCondition cdn = new TestPvarCondition();
cdn.Active = true;
CaTypeText catText = (CaTypeText)cdn.GetTypes()[0];
catText.Text = "$demo";
CaTypeQualifiedNumber catQualNum = (CaTypeQualifiedNumber)cdn.GetTypes()[1];
catQualNum.Qualifier = Qualifier.Exactly;
catQualNum.Value = 1;
tgrDemo.Conditions.Add(cdn);
// Action
EndMissionTriggerAction acn = new EndMissionTriggerAction();
acn.Active = true;
CaTypeWinLose catWinLose = (CaTypeWinLose)acn.GetTypes()[0];
catWinLose.Result = WinLoseType.Lose;
tgrDemo.Actions.Add(acn);
// Add this trigger temporarily
// Move it up to first place
AddTrigger(tgrDemo);
while (MoveUpTrigger(Side.side1, tgrDemo) != -1)
;
}
// Save triggers
Ini.Section sec = new Ini.Section("Triggers");
sec.Add(new Ini.Property("Count", m_alsTriggers.Count.ToString()));
foreach (Trigger tgr in m_alsTriggers) {
// Calc per side indexes
string strT = "";
for (int n = 0; n < m_aalsSideTriggers.Length; n++) {
ArrayList als = (ArrayList)m_aalsSideTriggers[n];
int j = als.IndexOf(tgr);
if (j != -1) {
if (strT != "")
strT += ",";
string strType = "k" + ((Side)n).ToString();
strT += strType + ":" + j.ToString();
}
}
sec.Add(new Ini.Property("T", strT));
// Save trigger contents
tgr.AddIniProperties(sec);
}
// Restore order
if (fDemoCheckTrigger) {
m_fModified = fModifiedSave;
RemoveTrigger(tgrDemo);
}
return sec;
}
public void LoadIni(Ini ini) {
Hashtable map = new Hashtable();
Trigger tgrCurrent = null;
Ini.Section sec = ini["Triggers"];
foreach (Ini.Property prop in sec.Properties) {
if (prop.Name == "Count") {
continue;
}
if (prop.Name == "T") {
tgrCurrent = new Trigger();
int nfSides = 0;
foreach (string key in prop.Value.Split(',')) {
Side side = (Side)int.Parse(key.Split(':')[0]);
nfSides |= SideToMask(side);
map.Add(key, tgrCurrent);
}
tgrCurrent.Sides = nfSides;
m_alsTriggers.Add(tgrCurrent);
continue;
}
if (prop.Name == "C") {
tgrCurrent.Conditions.Add(TriggerConditionLoader.LoadIni(prop.Value));
continue;
}
if (prop.Name == "A") {
tgrCurrent.Actions.Add(TriggerActionLoader.LoadIni(prop.Value));
continue;
}
}
// Add the triggers for each side in proper order
for (int side = 0; side < m_aalsSideTriggers.Length; side++) {
int index = 0;
while (true) {
bool fFound = false;
foreach (string key in map.Keys) {
int sideT = int.Parse(key.Split(':')[0]);
if (sideT != side) {
continue;
}
int indexT = int.Parse(key.Split(':')[1]);
if (indexT != index) {
continue;
}
fFound = true;
m_aalsSideTriggers[side].Add(map[key]);
}
if (!fFound) {
break;
}
index = index + 1;
}
}
// Go through all the triggers and search for demo check trigger.
// There should be only one, but check them all.
ArrayList alsRemove = new ArrayList();
foreach (Trigger tgr in m_alsTriggers) {
foreach (CaBase cab in tgr.Conditions) {
if (cab.GetType() == typeof(TestPvarCondition)) {
TestPvarCondition cdn = (TestPvarCondition)cab;
if (cdn.GetVariableString() == "$demo") {
alsRemove.Add(tgr);
break;
}
}
}
}
foreach (Trigger tgr in alsRemove) {
RemoveTrigger(tgr);
}
// Triggers have been modified
SetModified();
}
}
}