\r
namespace CarFire\r
{\r
+ /// <summary>\r
+ /// Trigger options modify trigger behavior.\r
+ /// </summary>\r
+ [Flags]\r
+ public enum TriggerOptions\r
+ {\r
+ Default = 0x00,\r
+ Reset = 0x01, // The script will be reset each time.\r
+ Once = 0x02, // Trigger can only be fired once.\r
+ Continuous = 0x04, // Trigger is always checked each update.\r
+ }\r
+\r
+\r
/// <summary>\r
/// A trigger is an invisible entity whose only purpose is\r
- /// to check a condition and run a script when the condition\r
- /// is right.\r
+ /// to check for a player to step on it and then run a script.\r
/// </summary>\r
public class Trigger : IEntity\r
{\r
/// <param name="game">The game reference.</param>\r
public Trigger(char identifier, Point position, Dictionary<string, string> info, Game game)\r
{\r
+ mId = identifier; \r
mGame = game;\r
- mPrevCondition = false;\r
mCoordinates = position;\r
\r
- string condition;\r
- if (info.TryGetValue("condition", out condition))\r
+ Functions functions = new Functions(this, game);\r
+\r
+ string script;\r
+ if (info.TryGetValue("script", out script))\r
{\r
- mCondition = new Script(condition, game);\r
+ mScript = new Script(script, functions);\r
}\r
- else throw new Exception("Triggers must define a condition script.");\r
+ else throw new Exception("Triggers must define a script.");\r
\r
- string eventt;\r
- if (info.TryGetValue("event", out eventt))\r
+ string options;\r
+ if (info.TryGetValue("options", out options))\r
{\r
- mEvent = new Script(eventt, game);\r
+ string[] list = Parse.List(options);\r
+ if (list != null)\r
+ {\r
+ foreach (string option in list)\r
+ {\r
+ TriggerOptions? flag = Parse.Constant<TriggerOptions>(option);\r
+ if (flag != null) mFlags |= flag.Value;\r
+ }\r
+ }\r
}\r
- else throw new Exception("Triggers must define an event script.");\r
}\r
\r
/// <summary>\r
- /// Check the trigger condition and execute the event if the\r
- /// condition evaluates to true.\r
+ /// Check for a player and execute the trigger script if\r
+ /// there is a player on this cell.\r
/// </summary>\r
public void Call()\r
{\r
- Player player = mGame.GetPlayerAtCoordinates(mCoordinates);\r
- if (player != null)\r
+ if (!mIsExpired)\r
{\r
- bool condition = mCondition.Run(player);\r
- if (condition && condition != mPrevCondition)\r
+ Player player = mGame.GetPlayerAtCoordinates(mCoordinates);\r
+ if (player != null)\r
{\r
- mEvent.Run(player);\r
+ if (!mIsFinished || (mFlags & TriggerOptions.Continuous) == TriggerOptions.Continuous)\r
+ {\r
+ mIsFinished = mScript.Run(player);\r
+ if (mIsFinished && (mFlags & TriggerOptions.Once) == TriggerOptions.Once) mIsExpired = true;\r
+ else if ((mFlags & TriggerOptions.Reset) == TriggerOptions.Reset) mScript.Reset();\r
+ }\r
}\r
- mPrevCondition = condition;\r
- }\r
- else\r
- {\r
- mPrevCondition = false;\r
+ else mIsFinished = false;\r
}\r
}\r
\r
\r
public Vector2 Position\r
{\r
- get { return Vector2.Zero; }\r
+ get { return new Vector2(mCoordinates.X, mCoordinates.Y); }\r
}\r
\r
public Point Coordinates\r
{\r
get { return mCoordinates; }\r
+ set { mCoordinates = value; }\r
+ }\r
+\r
+ public char Identifier\r
+ {\r
+ get { return mId; }\r
+ }\r
+\r
+ public Game Game\r
+ {\r
+ get { return mGame; }\r
+ }\r
+\r
+ #endregion\r
+\r
+\r
+ #region Private Types\r
+\r
+ /// <summary>\r
+ /// The script bindings.\r
+ /// </summary>\r
+ class Functions\r
+ {\r
+ // Always evaluates to true.\r
+ public bool True(Player player, string[] args)\r
+ {\r
+ return true;\r
+ }\r
+\r
+ // Always evaluates to false.\r
+ public bool False(Player player, string[] args)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // Check the player's inventory for an entity.\r
+ // Arg1: Entity identifier.\r
+ public bool Has(Player player, string[] args)\r
+ {\r
+ if (args.Length == 0) return false;\r
+\r
+ char? entity = Parse.Char(args[0]);\r
+ if (entity != null)\r
+ {\r
+ foreach (IEntity item in player.Inventory)\r
+ {\r
+ if (entity == item.Identifier) return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ // Put the trigger in the player's inventory.\r
+ public bool PickUp(Player player, string[] args)\r
+ {\r
+ IEntity entity = mGame.RemoveEntity(mTrigger);\r
+ if (entity != null)\r
+ {\r
+ player.Inventory.Add(entity);\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ // Drop an entity from the player's inventory here.\r
+ // Arg1: Entity identifier.\r
+ public bool Drop(Player player, string[] args)\r
+ {\r
+ if (args.Length == 0) return false;\r
+\r
+ char? entity = Parse.Char(args[0]);\r
+ if (entity != null)\r
+ {\r
+ foreach (IEntity item in player.Inventory)\r
+ {\r
+ if (entity == item.Identifier)\r
+ {\r
+ player.Inventory.Remove(item);\r
+ mGame.State.Entities.Add(item);\r
+ item.Coordinates = mTrigger.Coordinates;\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ // Use an entity in the player's inventory, disposing it.\r
+ // Arg1: Entity identifier.\r
+ public bool Use(Player player, string[] args)\r
+ {\r
+ if (args.Length == 0) return false;\r
+\r
+ char? entity = Parse.Char(args[0]);\r
+ if (entity != null)\r
+ {\r
+ foreach (IEntity item in player.Inventory)\r
+ {\r
+ if (entity == item.Identifier)\r
+ {\r
+ player.Inventory.Remove(item);\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ // Wait for a ceretain number of ticks.\r
+ // Arg1: Number of ticks.\r
+ public bool Wait(Player player, string[] args)\r
+ {\r
+ if (args.Length == 0) return false;\r
+\r
+ if (mTicks == 0)\r
+ {\r
+ int? timer = Parse.Integer(args[0]);\r
+ if (timer != null)\r
+ {\r
+ mTicks = 1;\r
+ mTimerTicks = timer.Value;\r
+ }\r
+ }\r
+ else if (++mTicks >= mTimerTicks)\r
+ {\r
+ mTicks = 0;\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ // Print each argument to the console as a string.\r
+ public bool Print(Player player, string[] args)\r
+ {\r
+ foreach (string arg in args)\r
+ {\r
+ string line = Parse.String(arg);\r
+ if (line != null) Console.WriteLine(line);\r
+ }\r
+ return true;\r
+ }\r
+\r
+ // Change a cell's tile on the map.\r
+ // Arg1: The coordinates.\r
+ // Arg2: The character representing the tile.\r
+ public bool Set(Player player, string[] args)\r
+ {\r
+ if (args.Length < 2) return false;\r
+\r
+ Point? coord = Parse.Coordinates(args[0]);\r
+ if (coord != null)\r
+ {\r
+ char? tile = Parse.Char(args[1]);\r
+ if (tile != null)\r
+ {\r
+ mGame.State.Map.SetCell(coord.Value, tile.Value);\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ // Move on to the next level.\r
+ public bool Next(Player player, string[] args)\r
+ {\r
+ mGame.AdvanceLevel();\r
+ return true;\r
+ }\r
+\r
+ // Restart the current level.\r
+ public bool Reset(Player player, string[] args)\r
+ {\r
+ mGame.Reset();\r
+ return true;\r
+ }\r
+\r
+\r
+ public Functions(IEntity trigger, Game game)\r
+ {\r
+ mTrigger = trigger;\r
+ mGame = game;\r
+ }\r
+\r
+ IEntity mTrigger;\r
+ Game mGame;\r
+ int mTicks;\r
+ int mTimerTicks;\r
}\r
\r
#endregion\r
\r
#region Private Variables\r
\r
- Script mCondition;\r
- Script mEvent;\r
+ Script mScript;\r
+\r
+ TriggerOptions mFlags;\r
+ bool mIsFinished;\r
+ bool mIsExpired;\r
+\r
+ char mId;\r
Game mGame;\r
- bool mPrevCondition;\r
Point mCoordinates;\r
\r
#endregion\r