From d167160264cd2c33de81a71039eddbb959c40bb2 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 23 Apr 2010 17:53:44 +0000 Subject: [PATCH] Fixed path finder thrown exception when finding a path to the cell you are already at. Triggers implemented. Initial scripting implemented. Map stable renamed to level1.cfmap. Campaign maps will be named like this... level1, level2, etc. Fixed a bug where entities were not being reported as occupying a cell. git-svn-id: https://bd85.net/svn/cs3505_group@140 92bb83a3-7c8f-8a45-bc97-515c4e399668 --- CarFire/CarFire/CarFire/CarFire.csproj | 1 + .../CarFire/Content/Content.contentproj | 4 +- .../Maps/{stable.cfmap => level1.cfmap} | 13 +- CarFire/CarFire/CarFire/Game.cs | 30 +++- CarFire/CarFire/CarFire/Parse.cs | 2 +- CarFire/CarFire/CarFire/PathFinder.cs | 2 +- CarFire/CarFire/CarFire/SaberMonster.cs | 16 +- CarFire/CarFire/CarFire/Script.cs | 137 +++++++++++++++--- CarFire/CarFire/CarFire/Trigger.cs | 92 ++++++++++++ 9 files changed, 260 insertions(+), 37 deletions(-) rename CarFire/CarFire/CarFire/Content/Maps/{stable.cfmap => level1.cfmap} (84%) create mode 100644 CarFire/CarFire/CarFire/Trigger.cs diff --git a/CarFire/CarFire/CarFire/CarFire.csproj b/CarFire/CarFire/CarFire/CarFire.csproj index 4353712..f4c5b70 100644 --- a/CarFire/CarFire/CarFire/CarFire.csproj +++ b/CarFire/CarFire/CarFire/CarFire.csproj @@ -108,6 +108,7 @@ + diff --git a/CarFire/CarFire/CarFire/Content/Content.contentproj b/CarFire/CarFire/CarFire/Content/Content.contentproj index 9416152..971b516 100644 --- a/CarFire/CarFire/CarFire/Content/Content.contentproj +++ b/CarFire/CarFire/CarFire/Content/Content.contentproj @@ -123,8 +123,8 @@ - - stable + + level1 MapImporter PassThroughProcessor diff --git a/CarFire/CarFire/CarFire/Content/Maps/stable.cfmap b/CarFire/CarFire/CarFire/Content/Maps/level1.cfmap similarity index 84% rename from CarFire/CarFire/CarFire/Content/Maps/stable.cfmap rename to CarFire/CarFire/CarFire/Content/Maps/level1.cfmap index 385626c..db46b43 100644 --- a/CarFire/CarFire/CarFire/Content/Maps/stable.cfmap +++ b/CarFire/CarFire/CarFire/Content/Maps/level1.cfmap @@ -1,5 +1,3 @@ -; This map should load and function just fine. - [metadata] author = Chaz McGarvey levelname = Stable @@ -13,13 +11,18 @@ speed = 10 path = [16,8] [20,6] wait(5) [56,9] [71,17] [75,2] [11,13] +[T] + type = Trigger + condition = Print("Trigger tested.") False() + event = Print("Trigger fired!") + [maptable] +------------------------------------------------------------------------------+ -| | +|T | | 1 | -| | +| M | | 2 +---- | -| | | +| | M | | 3 | | | |------------------------------------------ | | 4 | | | diff --git a/CarFire/CarFire/CarFire/Game.cs b/CarFire/CarFire/CarFire/Game.cs index 3808841..45b79d1 100644 --- a/CarFire/CarFire/CarFire/Game.cs +++ b/CarFire/CarFire/CarFire/Game.cs @@ -25,7 +25,7 @@ namespace CarFire public Map Map; public List Entities = new List(); public List mProjectiles = new List(); - public Player[] mCharacters = new Player[4]; + public Player[] mCharacters; public Display mDisplay; #endregion @@ -42,6 +42,8 @@ namespace CarFire mNumberOfPlayers = numPlayers; mFrameNumber = 0; + mCharacters = new Player[numPlayers]; + mIsGameOver = new bool[numPlayers]; mIsTerminated = new bool[numPlayers]; @@ -223,7 +225,7 @@ namespace CarFire foreach (IEntity entity in State.Entities) { Point coordinates = entity.Coordinates; - grid[coordinates.X, coordinates.Y] = true; + if (State.Map.IsCellOpen(coordinates)) grid[coordinates.X, coordinates.Y] = false; } return grid; } @@ -233,13 +235,29 @@ namespace CarFire #region Public Methods - public bool IsCellOpen(Point point) + + public IEntity GetEntityAtCoordinates(Point point) { - if (!State.Map.IsCellOpen(point)) return false; foreach (IEntity entity in State.Entities) { - if (entity.Coordinates == point) return false; + if (entity.Coordinates == point) return entity; + } + return null; + } + + public Player GetPlayerAtCoordinates(Point point) + { + foreach (Player player in State.mCharacters) + { + if (player != null && player.Coordinates == point) return player; } + return null; + } + + public bool IsCellOpen(Point point) + { + if (!State.Map.IsCellOpen(point)) return false; + if (GetEntityAtCoordinates(point) != null) return false; return true; } @@ -311,7 +329,7 @@ namespace CarFire State.mDisplay = new Display(this); State.mDisplay.LoadContent(mContentManager); - State.Map = mContentManager.Load("Maps/stable"); + State.Map = mContentManager.Load("Maps/level1"); State.Entities = State.Map.GetAllEntities(this); Map.DefaultTile = mContentManager.Load("default"); diff --git a/CarFire/CarFire/CarFire/Parse.cs b/CarFire/CarFire/CarFire/Parse.cs index bb2e9c1..4c2abcc 100644 --- a/CarFire/CarFire/CarFire/Parse.cs +++ b/CarFire/CarFire/CarFire/Parse.cs @@ -181,7 +181,7 @@ namespace CarFire /// Parses a function. /// /// Text. - /// An array two strings containing the function name and + /// An array with two strings containing the function name and /// parameter-list, in that order, or null if parsing failed. public static string[] Function(string atom) { diff --git a/CarFire/CarFire/CarFire/PathFinder.cs b/CarFire/CarFire/CarFire/PathFinder.cs index 53e148d..c37e518 100644 --- a/CarFire/CarFire/CarFire/PathFinder.cs +++ b/CarFire/CarFire/CarFire/PathFinder.cs @@ -129,7 +129,7 @@ namespace CarFire List list = new List(); cell = cell.Parent; - while (cell.Point != start) + while (cell != null && cell.Point != start) { list.Add(cell.Point); cell = cell.Parent; diff --git a/CarFire/CarFire/CarFire/SaberMonster.cs b/CarFire/CarFire/CarFire/SaberMonster.cs index c2932ee..ce59169 100644 --- a/CarFire/CarFire/CarFire/SaberMonster.cs +++ b/CarFire/CarFire/CarFire/SaberMonster.cs @@ -100,8 +100,12 @@ namespace CarFire PathFinder pathFinder = new PathFinder(mGame.Grid); mPath = new List(32); mPath.Add(Coordinates); - mPath.AddRange(pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex])); - mPath.Add(mIdlePath[mIdlePathIndex]); + List path = pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex]); + if (path != null) + { + mPath.AddRange(path); + mPath.Add(mIdlePath[mIdlePathIndex]); + } mPathIndex = 0; } @@ -115,8 +119,12 @@ namespace CarFire PathFinder pathFinder = new PathFinder(mGame.Grid); mPath = new List(32); mPath.Add(Coordinates); - mPath.AddRange(pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex % mIdlePath.Count])); - mPath.Add(mIdlePath[mIdlePathIndex % mIdlePath.Count]); + List path = pathFinder.GetPath(mMotion.Coordinates, mIdlePath[mIdlePathIndex % mIdlePath.Count]); + if (path != null) + { + mPath.AddRange(path); + mPath.Add(mIdlePath[mIdlePathIndex % mIdlePath.Count]); + } mPathIndex = 0; } diff --git a/CarFire/CarFire/CarFire/Script.cs b/CarFire/CarFire/CarFire/Script.cs index 5ae6908..146bb22 100644 --- a/CarFire/CarFire/CarFire/Script.cs +++ b/CarFire/CarFire/CarFire/Script.cs @@ -2,49 +2,150 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Reflection; +using System.Diagnostics; namespace CarFire { public class Script { - #region Public Types + #region Public Properties - public enum Status + public bool IsRunning { get { return mIsRunning; } } + + #endregion + + + #region Public Methods + + public Script(string code, Game game) { - Waiting, - Done, + mGame = game; + + string[] functions = Parse.List(code); + if (functions != null) + { + foreach (string function in functions) + { + string[] parts = Parse.Function(function); + if (parts != null) + { + string[] args = Parse.List(parts[1]); + if (args != null) + { + Function func = new Function(parts[0], args); + mFunctions.Add(func); + } + else throw new Exception("Arguments could not be parsed: " + parts[1]); + } + else throw new Exception("Function could not be parsed: " + function); + } + } + else throw new Exception("Script could not be parsed: " + code); } - public enum Function + public bool Run(Player player) { - Create, - Has, - Play, - Remove, - UseUp, - Wait, + bool result = false; + + if (!mIsRunning) + { + mIsRunning = true; + mRunningIndex = 0; + } + + for (; mRunningIndex < mFunctions.Count; mRunningIndex++) + { + result = Call(mRunningIndex, player); + if (!result) break; + } + + if (mRunningIndex >= mFunctions.Count - 1) mIsRunning = false; + return result; } #endregion - #region Public Methods + #region Private Methods - public Script(string code) + bool Call(int index, Player player) { + Debug.Assert(0 <= index && index < mFunctions.Count); + try + { + object[] args = new object[2]; + args[0] = player; + args[1] = mFunctions[index].Arguments; + return (bool)typeof(Impl).InvokeMember(mFunctions[index].Name, BindingFlags.InvokeMethod, null, null, args); + } +#pragma warning disable 0168 + catch (System.MissingMethodException ex) +#pragma warning restore 0168 + { + throw new Exception("Function could not be found: " + mFunctions[index].Name); + } } - public Status Run() + #endregion + + + #region Private Types + + class Impl { - return Status.Done; + public static bool True(Player player, string[] args) + { + return true; + } + + public static bool False(Player player, string[] args) + { + return false; + } + + public static bool Has(Player player, string[] args) + { + return false; + } + + public static bool Print(Player player, string[] args) + { + foreach (string arg in args) + { + string line = Parse.String(arg); + if (line != null) Console.WriteLine(line); + } + return true; + } } - public Status Evaluate(out bool value) + class Function { - value = true; - return Status.Done; + public string Name { get { return mName; } } + public string[] Arguments { get { return mArgs; } } + + public Function(string name, string[] args) + { + mName = name; + mArgs = args; + } + + string mName; + string[] mArgs; } #endregion + + + #region Private Variables + + Game mGame; + List mFunctions = new List(); + bool mIsRunning; + int mRunningIndex; + Impl mImpl = new Impl(); + + #endregion } } diff --git a/CarFire/CarFire/CarFire/Trigger.cs b/CarFire/CarFire/CarFire/Trigger.cs new file mode 100644 index 0000000..25cc11e --- /dev/null +++ b/CarFire/CarFire/CarFire/Trigger.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Content; + +namespace CarFire +{ + /// + /// A trigger is an invisible entity whose only purpose is + /// to check a condition and run a script when the condition + /// is right. + /// + public class Trigger : IEntity + { + #region Public Methods + + public Trigger(char identifier, Point position, Dictionary info, Game game) + { + mGame = game; + mPrevCondition = false; + mCoordinates = position; + + string condition; + if (info.TryGetValue("condition", out condition)) + { + mCondition = new Script(condition, game); + } + else throw new Exception("Triggers must define a condition script."); + + string eventt; + if (info.TryGetValue("event", out eventt)) + { + mEvent = new Script(eventt, game); + } + else throw new Exception("Triggers must define an event script."); + } + + public void Update(TimeSpan timeSpan) + { + Player player = mGame.GetPlayerAtCoordinates(mCoordinates); + if (player != null) + { + bool condition = mCondition.Run(player); + if (condition && condition != mPrevCondition) + { + mEvent.Run(player); + } + mPrevCondition = condition; + } + else + { + mPrevCondition = false; + } + } + + public void LoadContent(ContentManager contentManager) + { + // No implementation needed. + } + + public void Draw(SpriteBatch spriteBatch) + { + // No implementation needed. + } + + public Vector2 Position + { + get { return Vector2.Zero; } + } + + public Point Coordinates + { + get { return new Point(-1, -1); } + } + + #endregion + + + #region Private Variables + + Script mCondition; + Script mEvent; + Game mGame; + bool mPrevCondition; + Point mCoordinates; + + #endregion + } +} -- 2.43.0